File:  [local] / rpl / lapack / lapack / dsyconvf.f
Revision 1.6: download - view: text, annotated - select for diffs - revision graph
Mon Aug 7 08:39:08 2023 UTC (8 months, 3 weeks ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_35, rpl-4_1_34, HEAD
Première mise à jour de lapack et blas.

    1: *> \brief \b DSYCONVF
    2: *
    3: *  =========== DOCUMENTATION ===========
    4: *
    5: * Online html documentation available at
    6: *            http://www.netlib.org/lapack/explore-html/
    7: *
    8: *> \htmlonly
    9: *> Download DSYCONVF + dependencies
   10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsyconvf.f">
   11: *> [TGZ]</a>
   12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsyconvf.f">
   13: *> [ZIP]</a>
   14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsyconvf.f">
   15: *> [TXT]</a>
   16: *> \endhtmlonly
   17: *
   18: *  Definition:
   19: *  ===========
   20: *
   21: *       SUBROUTINE DSYCONVF( UPLO, WAY, N, A, LDA, E, IPIV, INFO )
   22: *
   23: *       .. Scalar Arguments ..
   24: *       CHARACTER          UPLO, WAY
   25: *       INTEGER            INFO, LDA, N
   26: *       ..
   27: *       .. Array Arguments ..
   28: *       INTEGER            IPIV( * )
   29: *       DOUBLE PRECISION   A( LDA, * ), E( * )
   30: *       ..
   31: *
   32: *
   33: *> \par Purpose:
   34: *  =============
   35: *>
   36: *> \verbatim
   37: *> If parameter WAY = 'C':
   38: *> DSYCONVF converts the factorization output format used in
   39: *> DSYTRF provided on entry in parameter A into the factorization
   40: *> output format used in DSYTRF_RK (or DSYTRF_BK) that is stored
   41: *> on exit in parameters A and E. It also converts in place details of
   42: *> the intechanges stored in IPIV from the format used in DSYTRF into
   43: *> the format used in DSYTRF_RK (or DSYTRF_BK).
   44: *>
   45: *> If parameter WAY = 'R':
   46: *> DSYCONVF performs the conversion in reverse direction, i.e.
   47: *> converts the factorization output format used in DSYTRF_RK
   48: *> (or DSYTRF_BK) provided on entry in parameters A and E into
   49: *> the factorization output format used in DSYTRF that is stored
   50: *> on exit in parameter A. It also converts in place details of
   51: *> the intechanges stored in IPIV from the format used in DSYTRF_RK
   52: *> (or DSYTRF_BK) into the format used in DSYTRF.
   53: *> \endverbatim
   54: *
   55: *  Arguments:
   56: *  ==========
   57: *
   58: *> \param[in] UPLO
   59: *> \verbatim
   60: *>          UPLO is CHARACTER*1
   61: *>          Specifies whether the details of the factorization are
   62: *>          stored as an upper or lower triangular matrix A.
   63: *>          = 'U':  Upper triangular
   64: *>          = 'L':  Lower triangular
   65: *> \endverbatim
   66: *>
   67: *> \param[in] WAY
   68: *> \verbatim
   69: *>          WAY is CHARACTER*1
   70: *>          = 'C': Convert
   71: *>          = 'R': Revert
   72: *> \endverbatim
   73: *>
   74: *> \param[in] N
   75: *> \verbatim
   76: *>          N is INTEGER
   77: *>          The order of the matrix A.  N >= 0.
   78: *> \endverbatim
   79: *>
   80: *> \param[in,out] A
   81: *> \verbatim
   82: *>          A is DOUBLE PRECISION array, dimension (LDA,N)
   83: *>
   84: *>          1) If WAY ='C':
   85: *>
   86: *>          On entry, contains factorization details in format used in
   87: *>          DSYTRF:
   88: *>            a) all elements of the symmetric block diagonal
   89: *>               matrix D on the diagonal of A and on superdiagonal
   90: *>               (or subdiagonal) of A, and
   91: *>            b) If UPLO = 'U': multipliers used to obtain factor U
   92: *>               in the superdiagonal part of A.
   93: *>               If UPLO = 'L': multipliers used to obtain factor L
   94: *>               in the superdiagonal part of A.
   95: *>
   96: *>          On exit, contains factorization details in format used in
   97: *>          DSYTRF_RK or DSYTRF_BK:
   98: *>            a) ONLY diagonal elements of the symmetric block diagonal
   99: *>               matrix D on the diagonal of A, i.e. D(k,k) = A(k,k);
  100: *>               (superdiagonal (or subdiagonal) elements of D
  101: *>                are stored on exit in array E), and
  102: *>            b) If UPLO = 'U': factor U in the superdiagonal part of A.
  103: *>               If UPLO = 'L': factor L in the subdiagonal part of A.
  104: *>
  105: *>          2) If WAY = 'R':
  106: *>
  107: *>          On entry, contains factorization details in format used in
  108: *>          DSYTRF_RK or DSYTRF_BK:
  109: *>            a) ONLY diagonal elements of the symmetric block diagonal
  110: *>               matrix D on the diagonal of A, i.e. D(k,k) = A(k,k);
  111: *>               (superdiagonal (or subdiagonal) elements of D
  112: *>                are stored on exit in array E), and
  113: *>            b) If UPLO = 'U': factor U in the superdiagonal part of A.
  114: *>               If UPLO = 'L': factor L in the subdiagonal part of A.
  115: *>
  116: *>          On exit, contains factorization details in format used in
  117: *>          DSYTRF:
  118: *>            a) all elements of the symmetric block diagonal
  119: *>               matrix D on the diagonal of A and on superdiagonal
  120: *>               (or subdiagonal) of A, and
  121: *>            b) If UPLO = 'U': multipliers used to obtain factor U
  122: *>               in the superdiagonal part of A.
  123: *>               If UPLO = 'L': multipliers used to obtain factor L
  124: *>               in the superdiagonal part of A.
  125: *> \endverbatim
  126: *>
  127: *> \param[in] LDA
  128: *> \verbatim
  129: *>          LDA is INTEGER
  130: *>          The leading dimension of the array A.  LDA >= max(1,N).
  131: *> \endverbatim
  132: *>
  133: *> \param[in,out] E
  134: *> \verbatim
  135: *>          E is DOUBLE PRECISION array, dimension (N)
  136: *>
  137: *>          1) If WAY ='C':
  138: *>
  139: *>          On entry, just a workspace.
  140: *>
  141: *>          On exit, contains the superdiagonal (or subdiagonal)
  142: *>          elements of the symmetric block diagonal matrix D
  143: *>          with 1-by-1 or 2-by-2 diagonal blocks, where
  144: *>          If UPLO = 'U': E(i) = D(i-1,i), i=2:N, E(1) is set to 0;
  145: *>          If UPLO = 'L': E(i) = D(i+1,i), i=1:N-1, E(N) is set to 0.
  146: *>
  147: *>          2) If WAY = 'R':
  148: *>
  149: *>          On entry, contains the superdiagonal (or subdiagonal)
  150: *>          elements of the symmetric block diagonal matrix D
  151: *>          with 1-by-1 or 2-by-2 diagonal blocks, where
  152: *>          If UPLO = 'U': E(i) = D(i-1,i),i=2:N, E(1) not referenced;
  153: *>          If UPLO = 'L': E(i) = D(i+1,i),i=1:N-1, E(N) not referenced.
  154: *>
  155: *>          On exit, is not changed
  156: *> \endverbatim
  157: *.
  158: *> \param[in,out] IPIV
  159: *> \verbatim
  160: *>          IPIV is INTEGER array, dimension (N)
  161: *>
  162: *>          1) If WAY ='C':
  163: *>          On entry, details of the interchanges and the block
  164: *>          structure of D in the format used in DSYTRF.
  165: *>          On exit, details of the interchanges and the block
  166: *>          structure of D in the format used in DSYTRF_RK
  167: *>          ( or DSYTRF_BK).
  168: *>
  169: *>          1) If WAY ='R':
  170: *>          On entry, details of the interchanges and the block
  171: *>          structure of D in the format used in DSYTRF_RK
  172: *>          ( or DSYTRF_BK).
  173: *>          On exit, details of the interchanges and the block
  174: *>          structure of D in the format used in DSYTRF.
  175: *> \endverbatim
  176: *>
  177: *> \param[out] INFO
  178: *> \verbatim
  179: *>          INFO is INTEGER
  180: *>          = 0:  successful exit
  181: *>          < 0:  if INFO = -i, the i-th argument had an illegal value
  182: *> \endverbatim
  183: *
  184: *  Authors:
  185: *  ========
  186: *
  187: *> \author Univ. of Tennessee
  188: *> \author Univ. of California Berkeley
  189: *> \author Univ. of Colorado Denver
  190: *> \author NAG Ltd.
  191: *
  192: *> \ingroup doubleSYcomputational
  193: *
  194: *> \par Contributors:
  195: *  ==================
  196: *>
  197: *> \verbatim
  198: *>
  199: *>  November 2017,  Igor Kozachenko,
  200: *>                  Computer Science Division,
  201: *>                  University of California, Berkeley
  202: *>
  203: *> \endverbatim
  204: *  =====================================================================
  205:       SUBROUTINE DSYCONVF( UPLO, WAY, N, A, LDA, E, IPIV, INFO )
  206: *
  207: *  -- LAPACK computational routine --
  208: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
  209: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  210: *
  211: *     .. Scalar Arguments ..
  212:       CHARACTER          UPLO, WAY
  213:       INTEGER            INFO, LDA, N
  214: *     ..
  215: *     .. Array Arguments ..
  216:       INTEGER            IPIV( * )
  217:       DOUBLE PRECISION   A( LDA, * ), E( * )
  218: *     ..
  219: *
  220: *  =====================================================================
  221: *
  222: *     .. Parameters ..
  223:       DOUBLE PRECISION   ZERO
  224:       PARAMETER          ( ZERO = 0.0D+0 )
  225: *     ..
  226: *     .. External Functions ..
  227:       LOGICAL            LSAME
  228:       EXTERNAL           LSAME
  229: *
  230: *     .. External Subroutines ..
  231:       EXTERNAL           DSWAP, XERBLA
  232: *     .. Local Scalars ..
  233:       LOGICAL            UPPER, CONVERT
  234:       INTEGER            I, IP
  235: *     ..
  236: *     .. Executable Statements ..
  237: *
  238:       INFO = 0
  239:       UPPER = LSAME( UPLO, 'U' )
  240:       CONVERT = LSAME( WAY, 'C' )
  241:       IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
  242:          INFO = -1
  243:       ELSE IF( .NOT.CONVERT .AND. .NOT.LSAME( WAY, 'R' ) ) THEN
  244:          INFO = -2
  245:       ELSE IF( N.LT.0 ) THEN
  246:          INFO = -3
  247:       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  248:          INFO = -5
  249: 
  250:       END IF
  251:       IF( INFO.NE.0 ) THEN
  252:          CALL XERBLA( 'DSYCONVF', -INFO )
  253:          RETURN
  254:       END IF
  255: *
  256: *     Quick return if possible
  257: *
  258:       IF( N.EQ.0 )
  259:      $   RETURN
  260: *
  261:       IF( UPPER ) THEN
  262: *
  263: *        Begin A is UPPER
  264: *
  265:          IF ( CONVERT ) THEN
  266: *
  267: *           Convert A (A is upper)
  268: *
  269: *
  270: *           Convert VALUE
  271: *
  272: *           Assign superdiagonal entries of D to array E and zero out
  273: *           corresponding entries in input storage A
  274: *
  275:             I = N
  276:             E( 1 ) = ZERO
  277:             DO WHILE ( I.GT.1 )
  278:                IF( IPIV( I ).LT.0 ) THEN
  279:                   E( I ) = A( I-1, I )
  280:                   E( I-1 ) = ZERO
  281:                   A( I-1, I ) = ZERO
  282:                   I = I - 1
  283:                ELSE
  284:                   E( I ) = ZERO
  285:                END IF
  286:                I = I - 1
  287:             END DO
  288: *
  289: *           Convert PERMUTATIONS and IPIV
  290: *
  291: *           Apply permutations to submatrices of upper part of A
  292: *           in factorization order where i decreases from N to 1
  293: *
  294:             I = N
  295:             DO WHILE ( I.GE.1 )
  296:                IF( IPIV( I ).GT.0 ) THEN
  297: *
  298: *                 1-by-1 pivot interchange
  299: *
  300: *                 Swap rows i and IPIV(i) in A(1:i,N-i:N)
  301: *
  302:                   IP = IPIV( I )
  303:                   IF( I.LT.N ) THEN
  304:                      IF( IP.NE.I ) THEN
  305:                         CALL DSWAP( N-I, A( I, I+1 ), LDA,
  306:      $                              A( IP, I+1 ), LDA )
  307:                      END IF
  308:                   END IF
  309: *
  310:                ELSE
  311: *
  312: *                 2-by-2 pivot interchange
  313: *
  314: *                 Swap rows i-1 and IPIV(i) in A(1:i,N-i:N)
  315: *
  316:                   IP = -IPIV( I )
  317:                   IF( I.LT.N ) THEN
  318:                      IF( IP.NE.(I-1) ) THEN
  319:                         CALL DSWAP( N-I, A( I-1, I+1 ), LDA,
  320:      $                              A( IP, I+1 ), LDA )
  321:                      END IF
  322:                   END IF
  323: *
  324: *                 Convert IPIV
  325: *                 There is no interchnge of rows i and and IPIV(i),
  326: *                 so this should be reflected in IPIV format for
  327: *                 *SYTRF_RK ( or *SYTRF_BK)
  328: *
  329:                   IPIV( I ) = I
  330: *
  331:                   I = I - 1
  332: *
  333:                END IF
  334:                I = I - 1
  335:             END DO
  336: *
  337:          ELSE
  338: *
  339: *           Revert A (A is upper)
  340: *
  341: *
  342: *           Revert PERMUTATIONS and IPIV
  343: *
  344: *           Apply permutations to submatrices of upper part of A
  345: *           in reverse factorization order where i increases from 1 to N
  346: *
  347:             I = 1
  348:             DO WHILE ( I.LE.N )
  349:                IF( IPIV( I ).GT.0 ) THEN
  350: *
  351: *                 1-by-1 pivot interchange
  352: *
  353: *                 Swap rows i and IPIV(i) in A(1:i,N-i:N)
  354: *
  355:                   IP = IPIV( I )
  356:                   IF( I.LT.N ) THEN
  357:                      IF( IP.NE.I ) THEN
  358:                         CALL DSWAP( N-I, A( IP, I+1 ), LDA,
  359:      $                              A( I, I+1 ), LDA )
  360:                      END IF
  361:                   END IF
  362: *
  363:                ELSE
  364: *
  365: *                 2-by-2 pivot interchange
  366: *
  367: *                 Swap rows i-1 and IPIV(i) in A(1:i,N-i:N)
  368: *
  369:                   I = I + 1
  370:                   IP = -IPIV( I )
  371:                   IF( I.LT.N ) THEN
  372:                      IF( IP.NE.(I-1) ) THEN
  373:                         CALL DSWAP( N-I, A( IP, I+1 ), LDA,
  374:      $                              A( I-1, I+1 ), LDA )
  375:                      END IF
  376:                   END IF
  377: *
  378: *                 Convert IPIV
  379: *                 There is one interchange of rows i-1 and IPIV(i-1),
  380: *                 so this should be recorded in two consecutive entries
  381: *                 in IPIV format for *SYTRF
  382: *
  383:                   IPIV( I ) = IPIV( I-1 )
  384: *
  385:                END IF
  386:                I = I + 1
  387:             END DO
  388: *
  389: *           Revert VALUE
  390: *           Assign superdiagonal entries of D from array E to
  391: *           superdiagonal entries of A.
  392: *
  393:             I = N
  394:             DO WHILE ( I.GT.1 )
  395:                IF( IPIV( I ).LT.0 ) THEN
  396:                   A( I-1, I ) = E( I )
  397:                   I = I - 1
  398:                END IF
  399:                I = I - 1
  400:             END DO
  401: *
  402: *        End A is UPPER
  403: *
  404:          END IF
  405: *
  406:       ELSE
  407: *
  408: *        Begin A is LOWER
  409: *
  410:          IF ( CONVERT ) THEN
  411: *
  412: *           Convert A (A is lower)
  413: *
  414: *
  415: *           Convert VALUE
  416: *           Assign subdiagonal entries of D to array E and zero out
  417: *           corresponding entries in input storage A
  418: *
  419:             I = 1
  420:             E( N ) = ZERO
  421:             DO WHILE ( I.LE.N )
  422:                IF( I.LT.N .AND. IPIV(I).LT.0 ) THEN
  423:                   E( I ) = A( I+1, I )
  424:                   E( I+1 ) = ZERO
  425:                   A( I+1, I ) = ZERO
  426:                   I = I + 1
  427:                ELSE
  428:                   E( I ) = ZERO
  429:                END IF
  430:                I = I + 1
  431:             END DO
  432: *
  433: *           Convert PERMUTATIONS and IPIV
  434: *
  435: *           Apply permutations to submatrices of lower part of A
  436: *           in factorization order where k increases from 1 to N
  437: *
  438:             I = 1
  439:             DO WHILE ( I.LE.N )
  440:                IF( IPIV( I ).GT.0 ) THEN
  441: *
  442: *                 1-by-1 pivot interchange
  443: *
  444: *                 Swap rows i and IPIV(i) in A(i:N,1:i-1)
  445: *
  446:                   IP = IPIV( I )
  447:                   IF ( I.GT.1 ) THEN
  448:                      IF( IP.NE.I ) THEN
  449:                         CALL DSWAP( I-1, A( I, 1 ), LDA,
  450:      $                              A( IP, 1 ), LDA )
  451:                      END IF
  452:                   END IF
  453: *
  454:                ELSE
  455: *
  456: *                 2-by-2 pivot interchange
  457: *
  458: *                 Swap rows i+1 and IPIV(i) in A(i:N,1:i-1)
  459: *
  460:                   IP = -IPIV( I )
  461:                   IF ( I.GT.1 ) THEN
  462:                      IF( IP.NE.(I+1) ) THEN
  463:                         CALL DSWAP( I-1, A( I+1, 1 ), LDA,
  464:      $                              A( IP, 1 ), LDA )
  465:                      END IF
  466:                   END IF
  467: *
  468: *                 Convert IPIV
  469: *                 There is no interchnge of rows i and and IPIV(i),
  470: *                 so this should be reflected in IPIV format for
  471: *                 *SYTRF_RK ( or *SYTRF_BK)
  472: *
  473:                   IPIV( I ) = I
  474: *
  475:                   I = I + 1
  476: *
  477:                END IF
  478:                I = I + 1
  479:             END DO
  480: *
  481:          ELSE
  482: *
  483: *           Revert A (A is lower)
  484: *
  485: *
  486: *           Revert PERMUTATIONS and IPIV
  487: *
  488: *           Apply permutations to submatrices of lower part of A
  489: *           in reverse factorization order where i decreases from N to 1
  490: *
  491:             I = N
  492:             DO WHILE ( I.GE.1 )
  493:                IF( IPIV( I ).GT.0 ) THEN
  494: *
  495: *                 1-by-1 pivot interchange
  496: *
  497: *                 Swap rows i and IPIV(i) in A(i:N,1:i-1)
  498: *
  499:                   IP = IPIV( I )
  500:                   IF ( I.GT.1 ) THEN
  501:                      IF( IP.NE.I ) THEN
  502:                         CALL DSWAP( I-1, A( IP, 1 ), LDA,
  503:      $                              A( I, 1 ), LDA )
  504:                      END IF
  505:                   END IF
  506: *
  507:                ELSE
  508: *
  509: *                 2-by-2 pivot interchange
  510: *
  511: *                 Swap rows i+1 and IPIV(i) in A(i:N,1:i-1)
  512: *
  513:                   I = I - 1
  514:                   IP = -IPIV( I )
  515:                   IF ( I.GT.1 ) THEN
  516:                      IF( IP.NE.(I+1) ) THEN
  517:                         CALL DSWAP( I-1, A( IP, 1 ), LDA,
  518:      $                              A( I+1, 1 ), LDA )
  519:                      END IF
  520:                   END IF
  521: *
  522: *                 Convert IPIV
  523: *                 There is one interchange of rows i+1 and IPIV(i+1),
  524: *                 so this should be recorded in consecutive entries
  525: *                 in IPIV format for *SYTRF
  526: *
  527:                   IPIV( I ) = IPIV( I+1 )
  528: *
  529:                END IF
  530:                I = I - 1
  531:             END DO
  532: *
  533: *           Revert VALUE
  534: *           Assign subdiagonal entries of D from array E to
  535: *           subgiagonal entries of A.
  536: *
  537:             I = 1
  538:             DO WHILE ( I.LE.N-1 )
  539:                IF( IPIV( I ).LT.0 ) THEN
  540:                   A( I + 1, I ) = E( I )
  541:                   I = I + 1
  542:                END IF
  543:                I = I + 1
  544:             END DO
  545: *
  546:          END IF
  547: *
  548: *        End A is LOWER
  549: *
  550:       END IF
  551: 
  552:       RETURN
  553: *
  554: *     End of DSYCONVF
  555: *
  556:       END

CVSweb interface <joel.bertrand@systella.fr>