File:  [local] / rpl / lapack / lapack / ztrsyl.f
Revision 1.18: download - view: text, annotated - select for diffs - revision graph
Mon Aug 7 08:39:42 2023 UTC (9 months 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 ZTRSYL
    2: *
    3: *  =========== DOCUMENTATION ===========
    4: *
    5: * Online html documentation available at
    6: *            http://www.netlib.org/lapack/explore-html/
    7: *
    8: *> \htmlonly
    9: *> Download ZTRSYL + dependencies
   10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ztrsyl.f">
   11: *> [TGZ]</a>
   12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ztrsyl.f">
   13: *> [ZIP]</a>
   14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ztrsyl.f">
   15: *> [TXT]</a>
   16: *> \endhtmlonly
   17: *
   18: *  Definition:
   19: *  ===========
   20: *
   21: *       SUBROUTINE ZTRSYL( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,
   22: *                          LDC, SCALE, INFO )
   23: *
   24: *       .. Scalar Arguments ..
   25: *       CHARACTER          TRANA, TRANB
   26: *       INTEGER            INFO, ISGN, LDA, LDB, LDC, M, N
   27: *       DOUBLE PRECISION   SCALE
   28: *       ..
   29: *       .. Array Arguments ..
   30: *       COMPLEX*16         A( LDA, * ), B( LDB, * ), C( LDC, * )
   31: *       ..
   32: *
   33: *
   34: *> \par Purpose:
   35: *  =============
   36: *>
   37: *> \verbatim
   38: *>
   39: *> ZTRSYL solves the complex Sylvester matrix equation:
   40: *>
   41: *>    op(A)*X + X*op(B) = scale*C or
   42: *>    op(A)*X - X*op(B) = scale*C,
   43: *>
   44: *> where op(A) = A or A**H, and A and B are both upper triangular. A is
   45: *> M-by-M and B is N-by-N; the right hand side C and the solution X are
   46: *> M-by-N; and scale is an output scale factor, set <= 1 to avoid
   47: *> overflow in X.
   48: *> \endverbatim
   49: *
   50: *  Arguments:
   51: *  ==========
   52: *
   53: *> \param[in] TRANA
   54: *> \verbatim
   55: *>          TRANA is CHARACTER*1
   56: *>          Specifies the option op(A):
   57: *>          = 'N': op(A) = A    (No transpose)
   58: *>          = 'C': op(A) = A**H (Conjugate transpose)
   59: *> \endverbatim
   60: *>
   61: *> \param[in] TRANB
   62: *> \verbatim
   63: *>          TRANB is CHARACTER*1
   64: *>          Specifies the option op(B):
   65: *>          = 'N': op(B) = B    (No transpose)
   66: *>          = 'C': op(B) = B**H (Conjugate transpose)
   67: *> \endverbatim
   68: *>
   69: *> \param[in] ISGN
   70: *> \verbatim
   71: *>          ISGN is INTEGER
   72: *>          Specifies the sign in the equation:
   73: *>          = +1: solve op(A)*X + X*op(B) = scale*C
   74: *>          = -1: solve op(A)*X - X*op(B) = scale*C
   75: *> \endverbatim
   76: *>
   77: *> \param[in] M
   78: *> \verbatim
   79: *>          M is INTEGER
   80: *>          The order of the matrix A, and the number of rows in the
   81: *>          matrices X and C. M >= 0.
   82: *> \endverbatim
   83: *>
   84: *> \param[in] N
   85: *> \verbatim
   86: *>          N is INTEGER
   87: *>          The order of the matrix B, and the number of columns in the
   88: *>          matrices X and C. N >= 0.
   89: *> \endverbatim
   90: *>
   91: *> \param[in] A
   92: *> \verbatim
   93: *>          A is COMPLEX*16 array, dimension (LDA,M)
   94: *>          The upper triangular matrix A.
   95: *> \endverbatim
   96: *>
   97: *> \param[in] LDA
   98: *> \verbatim
   99: *>          LDA is INTEGER
  100: *>          The leading dimension of the array A. LDA >= max(1,M).
  101: *> \endverbatim
  102: *>
  103: *> \param[in] B
  104: *> \verbatim
  105: *>          B is COMPLEX*16 array, dimension (LDB,N)
  106: *>          The upper triangular matrix B.
  107: *> \endverbatim
  108: *>
  109: *> \param[in] LDB
  110: *> \verbatim
  111: *>          LDB is INTEGER
  112: *>          The leading dimension of the array B. LDB >= max(1,N).
  113: *> \endverbatim
  114: *>
  115: *> \param[in,out] C
  116: *> \verbatim
  117: *>          C is COMPLEX*16 array, dimension (LDC,N)
  118: *>          On entry, the M-by-N right hand side matrix C.
  119: *>          On exit, C is overwritten by the solution matrix X.
  120: *> \endverbatim
  121: *>
  122: *> \param[in] LDC
  123: *> \verbatim
  124: *>          LDC is INTEGER
  125: *>          The leading dimension of the array C. LDC >= max(1,M)
  126: *> \endverbatim
  127: *>
  128: *> \param[out] SCALE
  129: *> \verbatim
  130: *>          SCALE is DOUBLE PRECISION
  131: *>          The scale factor, scale, set <= 1 to avoid overflow in X.
  132: *> \endverbatim
  133: *>
  134: *> \param[out] INFO
  135: *> \verbatim
  136: *>          INFO is INTEGER
  137: *>          = 0: successful exit
  138: *>          < 0: if INFO = -i, the i-th argument had an illegal value
  139: *>          = 1: A and B have common or very close eigenvalues; perturbed
  140: *>               values were used to solve the equation (but the matrices
  141: *>               A and B are unchanged).
  142: *> \endverbatim
  143: *
  144: *  Authors:
  145: *  ========
  146: *
  147: *> \author Univ. of Tennessee
  148: *> \author Univ. of California Berkeley
  149: *> \author Univ. of Colorado Denver
  150: *> \author NAG Ltd.
  151: *
  152: *> \ingroup complex16SYcomputational
  153: *
  154: *  =====================================================================
  155:       SUBROUTINE ZTRSYL( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,
  156:      $                   LDC, SCALE, INFO )
  157: *
  158: *  -- LAPACK computational routine --
  159: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
  160: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  161: *
  162: *     .. Scalar Arguments ..
  163:       CHARACTER          TRANA, TRANB
  164:       INTEGER            INFO, ISGN, LDA, LDB, LDC, M, N
  165:       DOUBLE PRECISION   SCALE
  166: *     ..
  167: *     .. Array Arguments ..
  168:       COMPLEX*16         A( LDA, * ), B( LDB, * ), C( LDC, * )
  169: *     ..
  170: *
  171: *  =====================================================================
  172: *
  173: *     .. Parameters ..
  174:       DOUBLE PRECISION   ONE
  175:       PARAMETER          ( ONE = 1.0D+0 )
  176: *     ..
  177: *     .. Local Scalars ..
  178:       LOGICAL            NOTRNA, NOTRNB
  179:       INTEGER            J, K, L
  180:       DOUBLE PRECISION   BIGNUM, DA11, DB, EPS, SCALOC, SGN, SMIN,
  181:      $                   SMLNUM
  182:       COMPLEX*16         A11, SUML, SUMR, VEC, X11
  183: *     ..
  184: *     .. Local Arrays ..
  185:       DOUBLE PRECISION   DUM( 1 )
  186: *     ..
  187: *     .. External Functions ..
  188:       LOGICAL            LSAME
  189:       DOUBLE PRECISION   DLAMCH, ZLANGE
  190:       COMPLEX*16         ZDOTC, ZDOTU, ZLADIV
  191:       EXTERNAL           LSAME, DLAMCH, ZLANGE, ZDOTC, ZDOTU, ZLADIV
  192: *     ..
  193: *     .. External Subroutines ..
  194:       EXTERNAL           DLABAD, XERBLA, ZDSCAL
  195: *     ..
  196: *     .. Intrinsic Functions ..
  197:       INTRINSIC          ABS, DBLE, DCMPLX, DCONJG, DIMAG, MAX, MIN
  198: *     ..
  199: *     .. Executable Statements ..
  200: *
  201: *     Decode and Test input parameters
  202: *
  203:       NOTRNA = LSAME( TRANA, 'N' )
  204:       NOTRNB = LSAME( TRANB, 'N' )
  205: *
  206:       INFO = 0
  207:       IF( .NOT.NOTRNA .AND. .NOT.LSAME( TRANA, 'C' ) ) THEN
  208:          INFO = -1
  209:       ELSE IF( .NOT.NOTRNB .AND. .NOT.LSAME( TRANB, 'C' ) ) THEN
  210:          INFO = -2
  211:       ELSE IF( ISGN.NE.1 .AND. ISGN.NE.-1 ) THEN
  212:          INFO = -3
  213:       ELSE IF( M.LT.0 ) THEN
  214:          INFO = -4
  215:       ELSE IF( N.LT.0 ) THEN
  216:          INFO = -5
  217:       ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
  218:          INFO = -7
  219:       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  220:          INFO = -9
  221:       ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
  222:          INFO = -11
  223:       END IF
  224:       IF( INFO.NE.0 ) THEN
  225:          CALL XERBLA( 'ZTRSYL', -INFO )
  226:          RETURN
  227:       END IF
  228: *
  229: *     Quick return if possible
  230: *
  231:       SCALE = ONE
  232:       IF( M.EQ.0 .OR. N.EQ.0 )
  233:      $   RETURN
  234: *
  235: *     Set constants to control overflow
  236: *
  237:       EPS = DLAMCH( 'P' )
  238:       SMLNUM = DLAMCH( 'S' )
  239:       BIGNUM = ONE / SMLNUM
  240:       CALL DLABAD( SMLNUM, BIGNUM )
  241:       SMLNUM = SMLNUM*DBLE( M*N ) / EPS
  242:       BIGNUM = ONE / SMLNUM
  243:       SMIN = MAX( SMLNUM, EPS*ZLANGE( 'M', M, M, A, LDA, DUM ),
  244:      $       EPS*ZLANGE( 'M', N, N, B, LDB, DUM ) )
  245:       SGN = ISGN
  246: *
  247:       IF( NOTRNA .AND. NOTRNB ) THEN
  248: *
  249: *        Solve    A*X + ISGN*X*B = scale*C.
  250: *
  251: *        The (K,L)th block of X is determined starting from
  252: *        bottom-left corner column by column by
  253: *
  254: *            A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
  255: *
  256: *        Where
  257: *                    M                        L-1
  258: *          R(K,L) = SUM [A(K,I)*X(I,L)] +ISGN*SUM [X(K,J)*B(J,L)].
  259: *                  I=K+1                      J=1
  260: *
  261:          DO 30 L = 1, N
  262:             DO 20 K = M, 1, -1
  263: *
  264:                SUML = ZDOTU( M-K, A( K, MIN( K+1, M ) ), LDA,
  265:      $                C( MIN( K+1, M ), L ), 1 )
  266:                SUMR = ZDOTU( L-1, C( K, 1 ), LDC, B( 1, L ), 1 )
  267:                VEC = C( K, L ) - ( SUML+SGN*SUMR )
  268: *
  269:                SCALOC = ONE
  270:                A11 = A( K, K ) + SGN*B( L, L )
  271:                DA11 = ABS( DBLE( A11 ) ) + ABS( DIMAG( A11 ) )
  272:                IF( DA11.LE.SMIN ) THEN
  273:                   A11 = SMIN
  274:                   DA11 = SMIN
  275:                   INFO = 1
  276:                END IF
  277:                DB = ABS( DBLE( VEC ) ) + ABS( DIMAG( VEC ) )
  278:                IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
  279:                   IF( DB.GT.BIGNUM*DA11 )
  280:      $               SCALOC = ONE / DB
  281:                END IF
  282:                X11 = ZLADIV( VEC*DCMPLX( SCALOC ), A11 )
  283: *
  284:                IF( SCALOC.NE.ONE ) THEN
  285:                   DO 10 J = 1, N
  286:                      CALL ZDSCAL( M, SCALOC, C( 1, J ), 1 )
  287:    10             CONTINUE
  288:                   SCALE = SCALE*SCALOC
  289:                END IF
  290:                C( K, L ) = X11
  291: *
  292:    20       CONTINUE
  293:    30    CONTINUE
  294: *
  295:       ELSE IF( .NOT.NOTRNA .AND. NOTRNB ) THEN
  296: *
  297: *        Solve    A**H *X + ISGN*X*B = scale*C.
  298: *
  299: *        The (K,L)th block of X is determined starting from
  300: *        upper-left corner column by column by
  301: *
  302: *            A**H(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
  303: *
  304: *        Where
  305: *                   K-1                           L-1
  306: *          R(K,L) = SUM [A**H(I,K)*X(I,L)] + ISGN*SUM [X(K,J)*B(J,L)]
  307: *                   I=1                           J=1
  308: *
  309:          DO 60 L = 1, N
  310:             DO 50 K = 1, M
  311: *
  312:                SUML = ZDOTC( K-1, A( 1, K ), 1, C( 1, L ), 1 )
  313:                SUMR = ZDOTU( L-1, C( K, 1 ), LDC, B( 1, L ), 1 )
  314:                VEC = C( K, L ) - ( SUML+SGN*SUMR )
  315: *
  316:                SCALOC = ONE
  317:                A11 = DCONJG( A( K, K ) ) + SGN*B( L, L )
  318:                DA11 = ABS( DBLE( A11 ) ) + ABS( DIMAG( A11 ) )
  319:                IF( DA11.LE.SMIN ) THEN
  320:                   A11 = SMIN
  321:                   DA11 = SMIN
  322:                   INFO = 1
  323:                END IF
  324:                DB = ABS( DBLE( VEC ) ) + ABS( DIMAG( VEC ) )
  325:                IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
  326:                   IF( DB.GT.BIGNUM*DA11 )
  327:      $               SCALOC = ONE / DB
  328:                END IF
  329: *
  330:                X11 = ZLADIV( VEC*DCMPLX( SCALOC ), A11 )
  331: *
  332:                IF( SCALOC.NE.ONE ) THEN
  333:                   DO 40 J = 1, N
  334:                      CALL ZDSCAL( M, SCALOC, C( 1, J ), 1 )
  335:    40             CONTINUE
  336:                   SCALE = SCALE*SCALOC
  337:                END IF
  338:                C( K, L ) = X11
  339: *
  340:    50       CONTINUE
  341:    60    CONTINUE
  342: *
  343:       ELSE IF( .NOT.NOTRNA .AND. .NOT.NOTRNB ) THEN
  344: *
  345: *        Solve    A**H*X + ISGN*X*B**H = C.
  346: *
  347: *        The (K,L)th block of X is determined starting from
  348: *        upper-right corner column by column by
  349: *
  350: *            A**H(K,K)*X(K,L) + ISGN*X(K,L)*B**H(L,L) = C(K,L) - R(K,L)
  351: *
  352: *        Where
  353: *                    K-1
  354: *           R(K,L) = SUM [A**H(I,K)*X(I,L)] +
  355: *                    I=1
  356: *                           N
  357: *                     ISGN*SUM [X(K,J)*B**H(L,J)].
  358: *                          J=L+1
  359: *
  360:          DO 90 L = N, 1, -1
  361:             DO 80 K = 1, M
  362: *
  363:                SUML = ZDOTC( K-1, A( 1, K ), 1, C( 1, L ), 1 )
  364:                SUMR = ZDOTC( N-L, C( K, MIN( L+1, N ) ), LDC,
  365:      $                B( L, MIN( L+1, N ) ), LDB )
  366:                VEC = C( K, L ) - ( SUML+SGN*DCONJG( SUMR ) )
  367: *
  368:                SCALOC = ONE
  369:                A11 = DCONJG( A( K, K )+SGN*B( L, L ) )
  370:                DA11 = ABS( DBLE( A11 ) ) + ABS( DIMAG( A11 ) )
  371:                IF( DA11.LE.SMIN ) THEN
  372:                   A11 = SMIN
  373:                   DA11 = SMIN
  374:                   INFO = 1
  375:                END IF
  376:                DB = ABS( DBLE( VEC ) ) + ABS( DIMAG( VEC ) )
  377:                IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
  378:                   IF( DB.GT.BIGNUM*DA11 )
  379:      $               SCALOC = ONE / DB
  380:                END IF
  381: *
  382:                X11 = ZLADIV( VEC*DCMPLX( SCALOC ), A11 )
  383: *
  384:                IF( SCALOC.NE.ONE ) THEN
  385:                   DO 70 J = 1, N
  386:                      CALL ZDSCAL( M, SCALOC, C( 1, J ), 1 )
  387:    70             CONTINUE
  388:                   SCALE = SCALE*SCALOC
  389:                END IF
  390:                C( K, L ) = X11
  391: *
  392:    80       CONTINUE
  393:    90    CONTINUE
  394: *
  395:       ELSE IF( NOTRNA .AND. .NOT.NOTRNB ) THEN
  396: *
  397: *        Solve    A*X + ISGN*X*B**H = C.
  398: *
  399: *        The (K,L)th block of X is determined starting from
  400: *        bottom-left corner column by column by
  401: *
  402: *           A(K,K)*X(K,L) + ISGN*X(K,L)*B**H(L,L) = C(K,L) - R(K,L)
  403: *
  404: *        Where
  405: *                    M                          N
  406: *          R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B**H(L,J)]
  407: *                  I=K+1                      J=L+1
  408: *
  409:          DO 120 L = N, 1, -1
  410:             DO 110 K = M, 1, -1
  411: *
  412:                SUML = ZDOTU( M-K, A( K, MIN( K+1, M ) ), LDA,
  413:      $                C( MIN( K+1, M ), L ), 1 )
  414:                SUMR = ZDOTC( N-L, C( K, MIN( L+1, N ) ), LDC,
  415:      $                B( L, MIN( L+1, N ) ), LDB )
  416:                VEC = C( K, L ) - ( SUML+SGN*DCONJG( SUMR ) )
  417: *
  418:                SCALOC = ONE
  419:                A11 = A( K, K ) + SGN*DCONJG( B( L, L ) )
  420:                DA11 = ABS( DBLE( A11 ) ) + ABS( DIMAG( A11 ) )
  421:                IF( DA11.LE.SMIN ) THEN
  422:                   A11 = SMIN
  423:                   DA11 = SMIN
  424:                   INFO = 1
  425:                END IF
  426:                DB = ABS( DBLE( VEC ) ) + ABS( DIMAG( VEC ) )
  427:                IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
  428:                   IF( DB.GT.BIGNUM*DA11 )
  429:      $               SCALOC = ONE / DB
  430:                END IF
  431: *
  432:                X11 = ZLADIV( VEC*DCMPLX( SCALOC ), A11 )
  433: *
  434:                IF( SCALOC.NE.ONE ) THEN
  435:                   DO 100 J = 1, N
  436:                      CALL ZDSCAL( M, SCALOC, C( 1, J ), 1 )
  437:   100             CONTINUE
  438:                   SCALE = SCALE*SCALOC
  439:                END IF
  440:                C( K, L ) = X11
  441: *
  442:   110       CONTINUE
  443:   120    CONTINUE
  444: *
  445:       END IF
  446: *
  447:       RETURN
  448: *
  449: *     End of ZTRSYL
  450: *
  451:       END

CVSweb interface <joel.bertrand@systella.fr>