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