Annotation of rpl/lapack/lapack/dsytrf_rk.f, revision 1.1
1.1 ! bertrand 1: *> \brief \b DSYTRF_RK computes the factorization of a real symmetric indefinite matrix using the bounded Bunch-Kaufman (rook) diagonal pivoting method (BLAS3 blocked algorithm).
! 2: *
! 3: * =========== DOCUMENTATION ===========
! 4: *
! 5: * Online html documentation available at
! 6: * http://www.netlib.org/lapack/explore-html/
! 7: *
! 8: *> \htmlonly
! 9: *> Download DSYTRF_RK + dependencies
! 10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytrf_rk.f">
! 11: *> [TGZ]</a>
! 12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytrf_rk.f">
! 13: *> [ZIP]</a>
! 14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytrf_rk.f">
! 15: *> [TXT]</a>
! 16: *> \endhtmlonly
! 17: *
! 18: * Definition:
! 19: * ===========
! 20: *
! 21: * SUBROUTINE DSYTRF_RK( UPLO, N, A, LDA, E, IPIV, WORK, LWORK,
! 22: * INFO )
! 23: *
! 24: * .. Scalar Arguments ..
! 25: * CHARACTER UPLO
! 26: * INTEGER INFO, LDA, LWORK, N
! 27: * ..
! 28: * .. Array Arguments ..
! 29: * INTEGER IPIV( * )
! 30: * DOUBLE PRECISION A( LDA, * ), E ( * ), WORK( * )
! 31: * ..
! 32: *
! 33: *
! 34: *> \par Purpose:
! 35: * =============
! 36: *>
! 37: *> \verbatim
! 38: *> DSYTRF_RK computes the factorization of a real symmetric matrix A
! 39: *> using the bounded Bunch-Kaufman (rook) diagonal pivoting method:
! 40: *>
! 41: *> A = P*U*D*(U**T)*(P**T) or A = P*L*D*(L**T)*(P**T),
! 42: *>
! 43: *> where U (or L) is unit upper (or lower) triangular matrix,
! 44: *> U**T (or L**T) is the transpose of U (or L), P is a permutation
! 45: *> matrix, P**T is the transpose of P, and D is symmetric and block
! 46: *> diagonal with 1-by-1 and 2-by-2 diagonal blocks.
! 47: *>
! 48: *> This is the blocked version of the algorithm, calling Level 3 BLAS.
! 49: *> For more information see Further Details section.
! 50: *> \endverbatim
! 51: *
! 52: * Arguments:
! 53: * ==========
! 54: *
! 55: *> \param[in] UPLO
! 56: *> \verbatim
! 57: *> UPLO is CHARACTER*1
! 58: *> Specifies whether the upper or lower triangular part of the
! 59: *> symmetric matrix A is stored:
! 60: *> = 'U': Upper triangular
! 61: *> = 'L': Lower triangular
! 62: *> \endverbatim
! 63: *>
! 64: *> \param[in] N
! 65: *> \verbatim
! 66: *> N is INTEGER
! 67: *> The order of the matrix A. N >= 0.
! 68: *> \endverbatim
! 69: *>
! 70: *> \param[in,out] A
! 71: *> \verbatim
! 72: *> A is DOUBLE PRECISION array, dimension (LDA,N)
! 73: *> On entry, the symmetric matrix A.
! 74: *> If UPLO = 'U': the leading N-by-N upper triangular part
! 75: *> of A contains the upper triangular part of the matrix A,
! 76: *> and the strictly lower triangular part of A is not
! 77: *> referenced.
! 78: *>
! 79: *> If UPLO = 'L': the leading N-by-N lower triangular part
! 80: *> of A contains the lower triangular part of the matrix A,
! 81: *> and the strictly upper triangular part of A is not
! 82: *> referenced.
! 83: *>
! 84: *> On exit, contains:
! 85: *> a) ONLY diagonal elements of the symmetric block diagonal
! 86: *> matrix D on the diagonal of A, i.e. D(k,k) = A(k,k);
! 87: *> (superdiagonal (or subdiagonal) elements of D
! 88: *> are stored on exit in array E), and
! 89: *> b) If UPLO = 'U': factor U in the superdiagonal part of A.
! 90: *> If UPLO = 'L': factor L in the subdiagonal part of A.
! 91: *> \endverbatim
! 92: *>
! 93: *> \param[in] LDA
! 94: *> \verbatim
! 95: *> LDA is INTEGER
! 96: *> The leading dimension of the array A. LDA >= max(1,N).
! 97: *> \endverbatim
! 98: *>
! 99: *> \param[out] E
! 100: *> \verbatim
! 101: *> E is DOUBLE PRECISION array, dimension (N)
! 102: *> On exit, contains the superdiagonal (or subdiagonal)
! 103: *> elements of the symmetric block diagonal matrix D
! 104: *> with 1-by-1 or 2-by-2 diagonal blocks, where
! 105: *> If UPLO = 'U': E(i) = D(i-1,i), i=2:N, E(1) is set to 0;
! 106: *> If UPLO = 'L': E(i) = D(i+1,i), i=1:N-1, E(N) is set to 0.
! 107: *>
! 108: *> NOTE: For 1-by-1 diagonal block D(k), where
! 109: *> 1 <= k <= N, the element E(k) is set to 0 in both
! 110: *> UPLO = 'U' or UPLO = 'L' cases.
! 111: *> \endverbatim
! 112: *>
! 113: *> \param[out] IPIV
! 114: *> \verbatim
! 115: *> IPIV is INTEGER array, dimension (N)
! 116: *> IPIV describes the permutation matrix P in the factorization
! 117: *> of matrix A as follows. The absolute value of IPIV(k)
! 118: *> represents the index of row and column that were
! 119: *> interchanged with the k-th row and column. The value of UPLO
! 120: *> describes the order in which the interchanges were applied.
! 121: *> Also, the sign of IPIV represents the block structure of
! 122: *> the symmetric block diagonal matrix D with 1-by-1 or 2-by-2
! 123: *> diagonal blocks which correspond to 1 or 2 interchanges
! 124: *> at each factorization step. For more info see Further
! 125: *> Details section.
! 126: *>
! 127: *> If UPLO = 'U',
! 128: *> ( in factorization order, k decreases from N to 1 ):
! 129: *> a) A single positive entry IPIV(k) > 0 means:
! 130: *> D(k,k) is a 1-by-1 diagonal block.
! 131: *> If IPIV(k) != k, rows and columns k and IPIV(k) were
! 132: *> interchanged in the matrix A(1:N,1:N);
! 133: *> If IPIV(k) = k, no interchange occurred.
! 134: *>
! 135: *> b) A pair of consecutive negative entries
! 136: *> IPIV(k) < 0 and IPIV(k-1) < 0 means:
! 137: *> D(k-1:k,k-1:k) is a 2-by-2 diagonal block.
! 138: *> (NOTE: negative entries in IPIV appear ONLY in pairs).
! 139: *> 1) If -IPIV(k) != k, rows and columns
! 140: *> k and -IPIV(k) were interchanged
! 141: *> in the matrix A(1:N,1:N).
! 142: *> If -IPIV(k) = k, no interchange occurred.
! 143: *> 2) If -IPIV(k-1) != k-1, rows and columns
! 144: *> k-1 and -IPIV(k-1) were interchanged
! 145: *> in the matrix A(1:N,1:N).
! 146: *> If -IPIV(k-1) = k-1, no interchange occurred.
! 147: *>
! 148: *> c) In both cases a) and b), always ABS( IPIV(k) ) <= k.
! 149: *>
! 150: *> d) NOTE: Any entry IPIV(k) is always NONZERO on output.
! 151: *>
! 152: *> If UPLO = 'L',
! 153: *> ( in factorization order, k increases from 1 to N ):
! 154: *> a) A single positive entry IPIV(k) > 0 means:
! 155: *> D(k,k) is a 1-by-1 diagonal block.
! 156: *> If IPIV(k) != k, rows and columns k and IPIV(k) were
! 157: *> interchanged in the matrix A(1:N,1:N).
! 158: *> If IPIV(k) = k, no interchange occurred.
! 159: *>
! 160: *> b) A pair of consecutive negative entries
! 161: *> IPIV(k) < 0 and IPIV(k+1) < 0 means:
! 162: *> D(k:k+1,k:k+1) is a 2-by-2 diagonal block.
! 163: *> (NOTE: negative entries in IPIV appear ONLY in pairs).
! 164: *> 1) If -IPIV(k) != k, rows and columns
! 165: *> k and -IPIV(k) were interchanged
! 166: *> in the matrix A(1:N,1:N).
! 167: *> If -IPIV(k) = k, no interchange occurred.
! 168: *> 2) If -IPIV(k+1) != k+1, rows and columns
! 169: *> k-1 and -IPIV(k-1) were interchanged
! 170: *> in the matrix A(1:N,1:N).
! 171: *> If -IPIV(k+1) = k+1, no interchange occurred.
! 172: *>
! 173: *> c) In both cases a) and b), always ABS( IPIV(k) ) >= k.
! 174: *>
! 175: *> d) NOTE: Any entry IPIV(k) is always NONZERO on output.
! 176: *> \endverbatim
! 177: *>
! 178: *> \param[out] WORK
! 179: *> \verbatim
! 180: *> WORK is DOUBLE PRECISION array, dimension ( MAX(1,LWORK) ).
! 181: *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
! 182: *> \endverbatim
! 183: *>
! 184: *> \param[in] LWORK
! 185: *> \verbatim
! 186: *> LWORK is INTEGER
! 187: *> The length of WORK. LWORK >=1. For best performance
! 188: *> LWORK >= N*NB, where NB is the block size returned
! 189: *> by ILAENV.
! 190: *>
! 191: *> If LWORK = -1, then a workspace query is assumed;
! 192: *> the routine only calculates the optimal size of the WORK
! 193: *> array, returns this value as the first entry of the WORK
! 194: *> array, and no error message related to LWORK is issued
! 195: *> by XERBLA.
! 196: *> \endverbatim
! 197: *>
! 198: *> \param[out] INFO
! 199: *> \verbatim
! 200: *> INFO is INTEGER
! 201: *> = 0: successful exit
! 202: *>
! 203: *> < 0: If INFO = -k, the k-th argument had an illegal value
! 204: *>
! 205: *> > 0: If INFO = k, the matrix A is singular, because:
! 206: *> If UPLO = 'U': column k in the upper
! 207: *> triangular part of A contains all zeros.
! 208: *> If UPLO = 'L': column k in the lower
! 209: *> triangular part of A contains all zeros.
! 210: *>
! 211: *> Therefore D(k,k) is exactly zero, and superdiagonal
! 212: *> elements of column k of U (or subdiagonal elements of
! 213: *> column k of L ) are all zeros. The factorization has
! 214: *> been completed, but the block diagonal matrix D is
! 215: *> exactly singular, and division by zero will occur if
! 216: *> it is used to solve a system of equations.
! 217: *>
! 218: *> NOTE: INFO only stores the first occurrence of
! 219: *> a singularity, any subsequent occurrence of singularity
! 220: *> is not stored in INFO even though the factorization
! 221: *> always completes.
! 222: *> \endverbatim
! 223: *
! 224: * Authors:
! 225: * ========
! 226: *
! 227: *> \author Univ. of Tennessee
! 228: *> \author Univ. of California Berkeley
! 229: *> \author Univ. of Colorado Denver
! 230: *> \author NAG Ltd.
! 231: *
! 232: *> \date December 2016
! 233: *
! 234: *> \ingroup doubleSYcomputational
! 235: *
! 236: *> \par Further Details:
! 237: * =====================
! 238: *>
! 239: *> \verbatim
! 240: *> TODO: put correct description
! 241: *> \endverbatim
! 242: *
! 243: *> \par Contributors:
! 244: * ==================
! 245: *>
! 246: *> \verbatim
! 247: *>
! 248: *> December 2016, Igor Kozachenko,
! 249: *> Computer Science Division,
! 250: *> University of California, Berkeley
! 251: *>
! 252: *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas,
! 253: *> School of Mathematics,
! 254: *> University of Manchester
! 255: *>
! 256: *> \endverbatim
! 257: *
! 258: * =====================================================================
! 259: SUBROUTINE DSYTRF_RK( UPLO, N, A, LDA, E, IPIV, WORK, LWORK,
! 260: $ INFO )
! 261: *
! 262: * -- LAPACK computational routine (version 3.7.0) --
! 263: * -- LAPACK is a software package provided by Univ. of Tennessee, --
! 264: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
! 265: * December 2016
! 266: *
! 267: * .. Scalar Arguments ..
! 268: CHARACTER UPLO
! 269: INTEGER INFO, LDA, LWORK, N
! 270: * ..
! 271: * .. Array Arguments ..
! 272: INTEGER IPIV( * )
! 273: DOUBLE PRECISION A( LDA, * ), E( * ), WORK( * )
! 274: * ..
! 275: *
! 276: * =====================================================================
! 277: *
! 278: * .. Local Scalars ..
! 279: LOGICAL LQUERY, UPPER
! 280: INTEGER I, IINFO, IP, IWS, K, KB, LDWORK, LWKOPT,
! 281: $ NB, NBMIN
! 282: * ..
! 283: * .. External Functions ..
! 284: LOGICAL LSAME
! 285: INTEGER ILAENV
! 286: EXTERNAL LSAME, ILAENV
! 287: * ..
! 288: * .. External Subroutines ..
! 289: EXTERNAL DLASYF_RK, DSYTF2_RK, DSWAP, XERBLA
! 290: * ..
! 291: * .. Intrinsic Functions ..
! 292: INTRINSIC ABS, MAX
! 293: * ..
! 294: * .. Executable Statements ..
! 295: *
! 296: * Test the input parameters.
! 297: *
! 298: INFO = 0
! 299: UPPER = LSAME( UPLO, 'U' )
! 300: LQUERY = ( LWORK.EQ.-1 )
! 301: IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
! 302: INFO = -1
! 303: ELSE IF( N.LT.0 ) THEN
! 304: INFO = -2
! 305: ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
! 306: INFO = -4
! 307: ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN
! 308: INFO = -8
! 309: END IF
! 310: *
! 311: IF( INFO.EQ.0 ) THEN
! 312: *
! 313: * Determine the block size
! 314: *
! 315: NB = ILAENV( 1, 'DSYTRF_RK', UPLO, N, -1, -1, -1 )
! 316: LWKOPT = N*NB
! 317: WORK( 1 ) = LWKOPT
! 318: END IF
! 319: *
! 320: IF( INFO.NE.0 ) THEN
! 321: CALL XERBLA( 'DSYTRF_RK', -INFO )
! 322: RETURN
! 323: ELSE IF( LQUERY ) THEN
! 324: RETURN
! 325: END IF
! 326: *
! 327: NBMIN = 2
! 328: LDWORK = N
! 329: IF( NB.GT.1 .AND. NB.LT.N ) THEN
! 330: IWS = LDWORK*NB
! 331: IF( LWORK.LT.IWS ) THEN
! 332: NB = MAX( LWORK / LDWORK, 1 )
! 333: NBMIN = MAX( 2, ILAENV( 2, 'DSYTRF_RK',
! 334: $ UPLO, N, -1, -1, -1 ) )
! 335: END IF
! 336: ELSE
! 337: IWS = 1
! 338: END IF
! 339: IF( NB.LT.NBMIN )
! 340: $ NB = N
! 341: *
! 342: IF( UPPER ) THEN
! 343: *
! 344: * Factorize A as U*D*U**T using the upper triangle of A
! 345: *
! 346: * K is the main loop index, decreasing from N to 1 in steps of
! 347: * KB, where KB is the number of columns factorized by DLASYF_RK;
! 348: * KB is either NB or NB-1, or K for the last block
! 349: *
! 350: K = N
! 351: 10 CONTINUE
! 352: *
! 353: * If K < 1, exit from loop
! 354: *
! 355: IF( K.LT.1 )
! 356: $ GO TO 15
! 357: *
! 358: IF( K.GT.NB ) THEN
! 359: *
! 360: * Factorize columns k-kb+1:k of A and use blocked code to
! 361: * update columns 1:k-kb
! 362: *
! 363: CALL DLASYF_RK( UPLO, K, NB, KB, A, LDA, E,
! 364: $ IPIV, WORK, LDWORK, IINFO )
! 365: ELSE
! 366: *
! 367: * Use unblocked code to factorize columns 1:k of A
! 368: *
! 369: CALL DSYTF2_RK( UPLO, K, A, LDA, E, IPIV, IINFO )
! 370: KB = K
! 371: END IF
! 372: *
! 373: * Set INFO on the first occurrence of a zero pivot
! 374: *
! 375: IF( INFO.EQ.0 .AND. IINFO.GT.0 )
! 376: $ INFO = IINFO
! 377: *
! 378: * No need to adjust IPIV
! 379: *
! 380: *
! 381: * Apply permutations to the leading panel 1:k-1
! 382: *
! 383: * Read IPIV from the last block factored, i.e.
! 384: * indices k-kb+1:k and apply row permutations to the
! 385: * last k+1 colunms k+1:N after that block
! 386: * (We can do the simple loop over IPIV with decrement -1,
! 387: * since the ABS value of IPIV( I ) represents the row index
! 388: * of the interchange with row i in both 1x1 and 2x2 pivot cases)
! 389: *
! 390: IF( K.LT.N ) THEN
! 391: DO I = K, ( K - KB + 1 ), -1
! 392: IP = ABS( IPIV( I ) )
! 393: IF( IP.NE.I ) THEN
! 394: CALL DSWAP( N-K, A( I, K+1 ), LDA,
! 395: $ A( IP, K+1 ), LDA )
! 396: END IF
! 397: END DO
! 398: END IF
! 399: *
! 400: * Decrease K and return to the start of the main loop
! 401: *
! 402: K = K - KB
! 403: GO TO 10
! 404: *
! 405: * This label is the exit from main loop over K decreasing
! 406: * from N to 1 in steps of KB
! 407: *
! 408: 15 CONTINUE
! 409: *
! 410: ELSE
! 411: *
! 412: * Factorize A as L*D*L**T using the lower triangle of A
! 413: *
! 414: * K is the main loop index, increasing from 1 to N in steps of
! 415: * KB, where KB is the number of columns factorized by DLASYF_RK;
! 416: * KB is either NB or NB-1, or N-K+1 for the last block
! 417: *
! 418: K = 1
! 419: 20 CONTINUE
! 420: *
! 421: * If K > N, exit from loop
! 422: *
! 423: IF( K.GT.N )
! 424: $ GO TO 35
! 425: *
! 426: IF( K.LE.N-NB ) THEN
! 427: *
! 428: * Factorize columns k:k+kb-1 of A and use blocked code to
! 429: * update columns k+kb:n
! 430: *
! 431: CALL DLASYF_RK( UPLO, N-K+1, NB, KB, A( K, K ), LDA, E( K ),
! 432: $ IPIV( K ), WORK, LDWORK, IINFO )
! 433:
! 434:
! 435: ELSE
! 436: *
! 437: * Use unblocked code to factorize columns k:n of A
! 438: *
! 439: CALL DSYTF2_RK( UPLO, N-K+1, A( K, K ), LDA, E( K ),
! 440: $ IPIV( K ), IINFO )
! 441: KB = N - K + 1
! 442: *
! 443: END IF
! 444: *
! 445: * Set INFO on the first occurrence of a zero pivot
! 446: *
! 447: IF( INFO.EQ.0 .AND. IINFO.GT.0 )
! 448: $ INFO = IINFO + K - 1
! 449: *
! 450: * Adjust IPIV
! 451: *
! 452: DO I = K, K + KB - 1
! 453: IF( IPIV( I ).GT.0 ) THEN
! 454: IPIV( I ) = IPIV( I ) + K - 1
! 455: ELSE
! 456: IPIV( I ) = IPIV( I ) - K + 1
! 457: END IF
! 458: END DO
! 459: *
! 460: * Apply permutations to the leading panel 1:k-1
! 461: *
! 462: * Read IPIV from the last block factored, i.e.
! 463: * indices k:k+kb-1 and apply row permutations to the
! 464: * first k-1 colunms 1:k-1 before that block
! 465: * (We can do the simple loop over IPIV with increment 1,
! 466: * since the ABS value of IPIV( I ) represents the row index
! 467: * of the interchange with row i in both 1x1 and 2x2 pivot cases)
! 468: *
! 469: IF( K.GT.1 ) THEN
! 470: DO I = K, ( K + KB - 1 ), 1
! 471: IP = ABS( IPIV( I ) )
! 472: IF( IP.NE.I ) THEN
! 473: CALL DSWAP( K-1, A( I, 1 ), LDA,
! 474: $ A( IP, 1 ), LDA )
! 475: END IF
! 476: END DO
! 477: END IF
! 478: *
! 479: * Increase K and return to the start of the main loop
! 480: *
! 481: K = K + KB
! 482: GO TO 20
! 483: *
! 484: * This label is the exit from main loop over K increasing
! 485: * from 1 to N in steps of KB
! 486: *
! 487: 35 CONTINUE
! 488: *
! 489: * End Lower
! 490: *
! 491: END IF
! 492: *
! 493: WORK( 1 ) = LWKOPT
! 494: RETURN
! 495: *
! 496: * End of DSYTRF_RK
! 497: *
! 498: END
CVSweb interface <joel.bertrand@systella.fr>