File:  [local] / rpl / lapack / lapack / dsytrf_rk.f
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Sat Jun 17 11:02:51 2017 UTC (6 years, 10 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Ajout des nouveaux fichiers pour lapack 3.7.0.

    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>