File:  [local] / rpl / lapack / lapack / zpstf2.f
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Sat Aug 7 13:22:43 2010 UTC (13 years, 9 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Mise à jour globale de Lapack 3.2.2.

    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>