Annotation of rpl/lapack/lapack/zpstf2.f, revision 1.1
1.1 ! bertrand 1: SUBROUTINE ZPSTF2( UPLO, N, A, LDA, PIV, RANK, TOL, WORK, INFO )
! 2: *
! 3: * -- LAPACK PROTOTYPE routine (version 3.2.2) --
! 4: * Craig Lucas, University of Manchester / NAG Ltd.
! 5: * October, 2008
! 6: *
! 7: * .. Scalar Arguments ..
! 8: DOUBLE PRECISION TOL
! 9: INTEGER INFO, LDA, N, RANK
! 10: CHARACTER UPLO
! 11: * ..
! 12: * .. Array Arguments ..
! 13: COMPLEX*16 A( LDA, * )
! 14: DOUBLE PRECISION WORK( 2*N )
! 15: INTEGER PIV( N )
! 16: * ..
! 17: *
! 18: * Purpose
! 19: * =======
! 20: *
! 21: * ZPSTF2 computes the Cholesky factorization with complete
! 22: * pivoting of a complex Hermitian positive semidefinite matrix A.
! 23: *
! 24: * The factorization has the form
! 25: * P' * A * P = U' * U , if UPLO = 'U',
! 26: * P' * A * P = L * L', if UPLO = 'L',
! 27: * where U is an upper triangular matrix and L is lower triangular, and
! 28: * P is stored as vector PIV.
! 29: *
! 30: * This algorithm does not attempt to check that A is positive
! 31: * semidefinite. This version of the algorithm calls level 2 BLAS.
! 32: *
! 33: * Arguments
! 34: * =========
! 35: *
! 36: * UPLO (input) CHARACTER*1
! 37: * Specifies whether the upper or lower triangular part of the
! 38: * symmetric matrix A is stored.
! 39: * = 'U': Upper triangular
! 40: * = 'L': Lower triangular
! 41: *
! 42: * N (input) INTEGER
! 43: * The order of the matrix A. N >= 0.
! 44: *
! 45: * A (input/output) COMPLEX*16 array, dimension (LDA,N)
! 46: * On entry, the symmetric matrix A. If UPLO = 'U', the leading
! 47: * n by n upper triangular part of A contains the upper
! 48: * triangular part of the matrix A, and the strictly lower
! 49: * triangular part of A is not referenced. If UPLO = 'L', the
! 50: * leading n by n lower triangular part of A contains the lower
! 51: * triangular part of the matrix A, and the strictly upper
! 52: * triangular part of A is not referenced.
! 53: *
! 54: * On exit, if INFO = 0, the factor U or L from the Cholesky
! 55: * factorization as above.
! 56: *
! 57: * PIV (output) INTEGER array, dimension (N)
! 58: * PIV is such that the nonzero entries are P( PIV(K), K ) = 1.
! 59: *
! 60: * RANK (output) INTEGER
! 61: * The rank of A given by the number of steps the algorithm
! 62: * completed.
! 63: *
! 64: * TOL (input) DOUBLE PRECISION
! 65: * User defined tolerance. If TOL < 0, then N*U*MAX( A( K,K ) )
! 66: * will be used. The algorithm terminates at the (K-1)st step
! 67: * if the pivot <= TOL.
! 68: *
! 69: * LDA (input) INTEGER
! 70: * The leading dimension of the array A. LDA >= max(1,N).
! 71: *
! 72: * WORK (workspace) DOUBLE PRECISION array, dimension (2*N)
! 73: * Work space.
! 74: *
! 75: * INFO (output) INTEGER
! 76: * < 0: If INFO = -K, the K-th argument had an illegal value,
! 77: * = 0: algorithm completed successfully, and
! 78: * > 0: the matrix A is either rank deficient with computed rank
! 79: * as returned in RANK, or is indefinite. See Section 7 of
! 80: * LAPACK Working Note #161 for further information.
! 81: *
! 82: * =====================================================================
! 83: *
! 84: * .. Parameters ..
! 85: DOUBLE PRECISION ONE, ZERO
! 86: PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )
! 87: COMPLEX*16 CONE
! 88: PARAMETER ( CONE = ( 1.0D+0, 0.0D+0 ) )
! 89: * ..
! 90: * .. Local Scalars ..
! 91: COMPLEX*16 ZTEMP
! 92: DOUBLE PRECISION AJJ, DSTOP, DTEMP
! 93: INTEGER I, ITEMP, J, PVT
! 94: LOGICAL UPPER
! 95: * ..
! 96: * .. External Functions ..
! 97: DOUBLE PRECISION DLAMCH
! 98: LOGICAL LSAME, DISNAN
! 99: EXTERNAL DLAMCH, LSAME, DISNAN
! 100: * ..
! 101: * .. External Subroutines ..
! 102: EXTERNAL ZDSCAL, ZGEMV, ZLACGV, ZSWAP, XERBLA
! 103: * ..
! 104: * .. Intrinsic Functions ..
! 105: INTRINSIC DBLE, DCONJG, MAX, SQRT
! 106: * ..
! 107: * .. Executable Statements ..
! 108: *
! 109: * Test the input parameters
! 110: *
! 111: INFO = 0
! 112: UPPER = LSAME( UPLO, 'U' )
! 113: IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
! 114: INFO = -1
! 115: ELSE IF( N.LT.0 ) THEN
! 116: INFO = -2
! 117: ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
! 118: INFO = -4
! 119: END IF
! 120: IF( INFO.NE.0 ) THEN
! 121: CALL XERBLA( 'ZPSTF2', -INFO )
! 122: RETURN
! 123: END IF
! 124: *
! 125: * Quick return if possible
! 126: *
! 127: IF( N.EQ.0 )
! 128: $ RETURN
! 129: *
! 130: * Initialize PIV
! 131: *
! 132: DO 100 I = 1, N
! 133: PIV( I ) = I
! 134: 100 CONTINUE
! 135: *
! 136: * Compute stopping value
! 137: *
! 138: DO 110 I = 1, N
! 139: WORK( I ) = DBLE( A( I, I ) )
! 140: 110 CONTINUE
! 141: PVT = MAXLOC( WORK( 1:N ), 1 )
! 142: AJJ = DBLE( A( PVT, PVT ) )
! 143: IF( AJJ.EQ.ZERO.OR.DISNAN( AJJ ) ) THEN
! 144: RANK = 0
! 145: INFO = 1
! 146: GO TO 200
! 147: END IF
! 148: *
! 149: * Compute stopping value if not supplied
! 150: *
! 151: IF( TOL.LT.ZERO ) THEN
! 152: DSTOP = N * DLAMCH( 'Epsilon' ) * AJJ
! 153: ELSE
! 154: DSTOP = TOL
! 155: END IF
! 156: *
! 157: * Set first half of WORK to zero, holds dot products
! 158: *
! 159: DO 120 I = 1, N
! 160: WORK( I ) = 0
! 161: 120 CONTINUE
! 162: *
! 163: IF( UPPER ) THEN
! 164: *
! 165: * Compute the Cholesky factorization P' * A * P = U' * U
! 166: *
! 167: DO 150 J = 1, N
! 168: *
! 169: * Find pivot, test for exit, else swap rows and columns
! 170: * Update dot products, compute possible pivots which are
! 171: * stored in the second half of WORK
! 172: *
! 173: DO 130 I = J, N
! 174: *
! 175: IF( J.GT.1 ) THEN
! 176: WORK( I ) = WORK( I ) +
! 177: $ DBLE( DCONJG( A( J-1, I ) )*
! 178: $ A( J-1, I ) )
! 179: END IF
! 180: WORK( N+I ) = DBLE( A( I, I ) ) - WORK( I )
! 181: *
! 182: 130 CONTINUE
! 183: *
! 184: IF( J.GT.1 ) THEN
! 185: ITEMP = MAXLOC( WORK( (N+J):(2*N) ), 1 )
! 186: PVT = ITEMP + J - 1
! 187: AJJ = WORK( N+PVT )
! 188: IF( AJJ.LE.DSTOP.OR.DISNAN( AJJ ) ) THEN
! 189: A( J, J ) = AJJ
! 190: GO TO 190
! 191: END IF
! 192: END IF
! 193: *
! 194: IF( J.NE.PVT ) THEN
! 195: *
! 196: * Pivot OK, so can now swap pivot rows and columns
! 197: *
! 198: A( PVT, PVT ) = A( J, J )
! 199: CALL ZSWAP( J-1, A( 1, J ), 1, A( 1, PVT ), 1 )
! 200: IF( PVT.LT.N )
! 201: $ CALL ZSWAP( N-PVT, A( J, PVT+1 ), LDA,
! 202: $ A( PVT, PVT+1 ), LDA )
! 203: DO 140 I = J + 1, PVT - 1
! 204: ZTEMP = DCONJG( A( J, I ) )
! 205: A( J, I ) = DCONJG( A( I, PVT ) )
! 206: A( I, PVT ) = ZTEMP
! 207: 140 CONTINUE
! 208: A( J, PVT ) = DCONJG( A( J, PVT ) )
! 209: *
! 210: * Swap dot products and PIV
! 211: *
! 212: DTEMP = WORK( J )
! 213: WORK( J ) = WORK( PVT )
! 214: WORK( PVT ) = DTEMP
! 215: ITEMP = PIV( PVT )
! 216: PIV( PVT ) = PIV( J )
! 217: PIV( J ) = ITEMP
! 218: END IF
! 219: *
! 220: AJJ = SQRT( AJJ )
! 221: A( J, J ) = AJJ
! 222: *
! 223: * Compute elements J+1:N of row J
! 224: *
! 225: IF( J.LT.N ) THEN
! 226: CALL ZLACGV( J-1, A( 1, J ), 1 )
! 227: CALL ZGEMV( 'Trans', J-1, N-J, -CONE, A( 1, J+1 ), LDA,
! 228: $ A( 1, J ), 1, CONE, A( J, J+1 ), LDA )
! 229: CALL ZLACGV( J-1, A( 1, J ), 1 )
! 230: CALL ZDSCAL( N-J, ONE / AJJ, A( J, J+1 ), LDA )
! 231: END IF
! 232: *
! 233: 150 CONTINUE
! 234: *
! 235: ELSE
! 236: *
! 237: * Compute the Cholesky factorization P' * A * P = L * L'
! 238: *
! 239: DO 180 J = 1, N
! 240: *
! 241: * Find pivot, test for exit, else swap rows and columns
! 242: * Update dot products, compute possible pivots which are
! 243: * stored in the second half of WORK
! 244: *
! 245: DO 160 I = J, N
! 246: *
! 247: IF( J.GT.1 ) THEN
! 248: WORK( I ) = WORK( I ) +
! 249: $ DBLE( DCONJG( A( I, J-1 ) )*
! 250: $ A( I, J-1 ) )
! 251: END IF
! 252: WORK( N+I ) = DBLE( A( I, I ) ) - WORK( I )
! 253: *
! 254: 160 CONTINUE
! 255: *
! 256: IF( J.GT.1 ) THEN
! 257: ITEMP = MAXLOC( WORK( (N+J):(2*N) ), 1 )
! 258: PVT = ITEMP + J - 1
! 259: AJJ = WORK( N+PVT )
! 260: IF( AJJ.LE.DSTOP.OR.DISNAN( AJJ ) ) THEN
! 261: A( J, J ) = AJJ
! 262: GO TO 190
! 263: END IF
! 264: END IF
! 265: *
! 266: IF( J.NE.PVT ) THEN
! 267: *
! 268: * Pivot OK, so can now swap pivot rows and columns
! 269: *
! 270: A( PVT, PVT ) = A( J, J )
! 271: CALL ZSWAP( J-1, A( J, 1 ), LDA, A( PVT, 1 ), LDA )
! 272: IF( PVT.LT.N )
! 273: $ CALL ZSWAP( N-PVT, A( PVT+1, J ), 1, A( PVT+1, PVT ),
! 274: $ 1 )
! 275: DO 170 I = J + 1, PVT - 1
! 276: ZTEMP = DCONJG( A( I, J ) )
! 277: A( I, J ) = DCONJG( A( PVT, I ) )
! 278: A( PVT, I ) = ZTEMP
! 279: 170 CONTINUE
! 280: A( PVT, J ) = DCONJG( A( PVT, J ) )
! 281: *
! 282: * Swap dot products and PIV
! 283: *
! 284: DTEMP = WORK( J )
! 285: WORK( J ) = WORK( PVT )
! 286: WORK( PVT ) = DTEMP
! 287: ITEMP = PIV( PVT )
! 288: PIV( PVT ) = PIV( J )
! 289: PIV( J ) = ITEMP
! 290: END IF
! 291: *
! 292: AJJ = SQRT( AJJ )
! 293: A( J, J ) = AJJ
! 294: *
! 295: * Compute elements J+1:N of column J
! 296: *
! 297: IF( J.LT.N ) THEN
! 298: CALL ZLACGV( J-1, A( J, 1 ), LDA )
! 299: CALL ZGEMV( 'No Trans', N-J, J-1, -CONE, A( J+1, 1 ),
! 300: $ LDA, A( J, 1 ), LDA, CONE, A( J+1, J ), 1 )
! 301: CALL ZLACGV( J-1, A( J, 1 ), LDA )
! 302: CALL ZDSCAL( N-J, ONE / AJJ, A( J+1, J ), 1 )
! 303: END IF
! 304: *
! 305: 180 CONTINUE
! 306: *
! 307: END IF
! 308: *
! 309: * Ran to completion, A has full rank
! 310: *
! 311: RANK = N
! 312: *
! 313: GO TO 200
! 314: 190 CONTINUE
! 315: *
! 316: * Rank is number of steps completed. Set INFO = 1 to signal
! 317: * that the factorization cannot be used to solve a system.
! 318: *
! 319: RANK = J - 1
! 320: INFO = 1
! 321: *
! 322: 200 CONTINUE
! 323: RETURN
! 324: *
! 325: * End of ZPSTF2
! 326: *
! 327: END
CVSweb interface <joel.bertrand@systella.fr>