Annotation of rpl/lapack/lapack/ztrsyl.f, revision 1.4

1.1       bertrand    1:       SUBROUTINE ZTRSYL( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,
                      2:      $                   LDC, SCALE, INFO )
                      3: *
                      4: *  -- LAPACK routine (version 3.2) --
                      5: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
                      6: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
                      7: *     November 2006
                      8: *
                      9: *     .. Scalar Arguments ..
                     10:       CHARACTER          TRANA, TRANB
                     11:       INTEGER            INFO, ISGN, LDA, LDB, LDC, M, N
                     12:       DOUBLE PRECISION   SCALE
                     13: *     ..
                     14: *     .. Array Arguments ..
                     15:       COMPLEX*16         A( LDA, * ), B( LDB, * ), C( LDC, * )
                     16: *     ..
                     17: *
                     18: *  Purpose
                     19: *  =======
                     20: *
                     21: *  ZTRSYL solves the complex Sylvester matrix equation:
                     22: *
                     23: *     op(A)*X + X*op(B) = scale*C or
                     24: *     op(A)*X - X*op(B) = scale*C,
                     25: *
                     26: *  where op(A) = A or A**H, and A and B are both upper triangular. A is
                     27: *  M-by-M and B is N-by-N; the right hand side C and the solution X are
                     28: *  M-by-N; and scale is an output scale factor, set <= 1 to avoid
                     29: *  overflow in X.
                     30: *
                     31: *  Arguments
                     32: *  =========
                     33: *
                     34: *  TRANA   (input) CHARACTER*1
                     35: *          Specifies the option op(A):
                     36: *          = 'N': op(A) = A    (No transpose)
                     37: *          = 'C': op(A) = A**H (Conjugate transpose)
                     38: *
                     39: *  TRANB   (input) CHARACTER*1
                     40: *          Specifies the option op(B):
                     41: *          = 'N': op(B) = B    (No transpose)
                     42: *          = 'C': op(B) = B**H (Conjugate transpose)
                     43: *
                     44: *  ISGN    (input) INTEGER
                     45: *          Specifies the sign in the equation:
                     46: *          = +1: solve op(A)*X + X*op(B) = scale*C
                     47: *          = -1: solve op(A)*X - X*op(B) = scale*C
                     48: *
                     49: *  M       (input) INTEGER
                     50: *          The order of the matrix A, and the number of rows in the
                     51: *          matrices X and C. M >= 0.
                     52: *
                     53: *  N       (input) INTEGER
                     54: *          The order of the matrix B, and the number of columns in the
                     55: *          matrices X and C. N >= 0.
                     56: *
                     57: *  A       (input) COMPLEX*16 array, dimension (LDA,M)
                     58: *          The upper triangular matrix A.
                     59: *
                     60: *  LDA     (input) INTEGER
                     61: *          The leading dimension of the array A. LDA >= max(1,M).
                     62: *
                     63: *  B       (input) COMPLEX*16 array, dimension (LDB,N)
                     64: *          The upper triangular matrix B.
                     65: *
                     66: *  LDB     (input) INTEGER
                     67: *          The leading dimension of the array B. LDB >= max(1,N).
                     68: *
                     69: *  C       (input/output) COMPLEX*16 array, dimension (LDC,N)
                     70: *          On entry, the M-by-N right hand side matrix C.
                     71: *          On exit, C is overwritten by the solution matrix X.
                     72: *
                     73: *  LDC     (input) INTEGER
                     74: *          The leading dimension of the array C. LDC >= max(1,M)
                     75: *
                     76: *  SCALE   (output) DOUBLE PRECISION
                     77: *          The scale factor, scale, set <= 1 to avoid overflow in X.
                     78: *
                     79: *  INFO    (output) INTEGER
                     80: *          = 0: successful exit
                     81: *          < 0: if INFO = -i, the i-th argument had an illegal value
                     82: *          = 1: A and B have common or very close eigenvalues; perturbed
                     83: *               values were used to solve the equation (but the matrices
                     84: *               A and B are unchanged).
                     85: *
                     86: *  =====================================================================
                     87: *
                     88: *     .. Parameters ..
                     89:       DOUBLE PRECISION   ONE
                     90:       PARAMETER          ( ONE = 1.0D+0 )
                     91: *     ..
                     92: *     .. Local Scalars ..
                     93:       LOGICAL            NOTRNA, NOTRNB
                     94:       INTEGER            J, K, L
                     95:       DOUBLE PRECISION   BIGNUM, DA11, DB, EPS, SCALOC, SGN, SMIN,
                     96:      $                   SMLNUM
                     97:       COMPLEX*16         A11, SUML, SUMR, VEC, X11
                     98: *     ..
                     99: *     .. Local Arrays ..
                    100:       DOUBLE PRECISION   DUM( 1 )
                    101: *     ..
                    102: *     .. External Functions ..
                    103:       LOGICAL            LSAME
                    104:       DOUBLE PRECISION   DLAMCH, ZLANGE
                    105:       COMPLEX*16         ZDOTC, ZDOTU, ZLADIV
                    106:       EXTERNAL           LSAME, DLAMCH, ZLANGE, ZDOTC, ZDOTU, ZLADIV
                    107: *     ..
                    108: *     .. External Subroutines ..
                    109:       EXTERNAL           DLABAD, XERBLA, ZDSCAL
                    110: *     ..
                    111: *     .. Intrinsic Functions ..
                    112:       INTRINSIC          ABS, DBLE, DCMPLX, DCONJG, DIMAG, MAX, MIN
                    113: *     ..
                    114: *     .. Executable Statements ..
                    115: *
                    116: *     Decode and Test input parameters
                    117: *
                    118:       NOTRNA = LSAME( TRANA, 'N' )
                    119:       NOTRNB = LSAME( TRANB, 'N' )
                    120: *
                    121:       INFO = 0
                    122:       IF( .NOT.NOTRNA .AND. .NOT.LSAME( TRANA, 'C' ) ) THEN
                    123:          INFO = -1
                    124:       ELSE IF( .NOT.NOTRNB .AND. .NOT.LSAME( TRANB, 'C' ) ) THEN
                    125:          INFO = -2
                    126:       ELSE IF( ISGN.NE.1 .AND. ISGN.NE.-1 ) THEN
                    127:          INFO = -3
                    128:       ELSE IF( M.LT.0 ) THEN
                    129:          INFO = -4
                    130:       ELSE IF( N.LT.0 ) THEN
                    131:          INFO = -5
                    132:       ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
                    133:          INFO = -7
                    134:       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
                    135:          INFO = -9
                    136:       ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
                    137:          INFO = -11
                    138:       END IF
                    139:       IF( INFO.NE.0 ) THEN
                    140:          CALL XERBLA( 'ZTRSYL', -INFO )
                    141:          RETURN
                    142:       END IF
                    143: *
                    144: *     Quick return if possible
                    145: *
                    146:       SCALE = ONE
                    147:       IF( M.EQ.0 .OR. N.EQ.0 )
                    148:      $   RETURN
                    149: *
                    150: *     Set constants to control overflow
                    151: *
                    152:       EPS = DLAMCH( 'P' )
                    153:       SMLNUM = DLAMCH( 'S' )
                    154:       BIGNUM = ONE / SMLNUM
                    155:       CALL DLABAD( SMLNUM, BIGNUM )
                    156:       SMLNUM = SMLNUM*DBLE( M*N ) / EPS
                    157:       BIGNUM = ONE / SMLNUM
                    158:       SMIN = MAX( SMLNUM, EPS*ZLANGE( 'M', M, M, A, LDA, DUM ),
                    159:      $       EPS*ZLANGE( 'M', N, N, B, LDB, DUM ) )
                    160:       SGN = ISGN
                    161: *
                    162:       IF( NOTRNA .AND. NOTRNB ) THEN
                    163: *
                    164: *        Solve    A*X + ISGN*X*B = scale*C.
                    165: *
                    166: *        The (K,L)th block of X is determined starting from
                    167: *        bottom-left corner column by column by
                    168: *
                    169: *            A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
                    170: *
                    171: *        Where
                    172: *                    M                        L-1
                    173: *          R(K,L) = SUM [A(K,I)*X(I,L)] +ISGN*SUM [X(K,J)*B(J,L)].
                    174: *                  I=K+1                      J=1
                    175: *
                    176:          DO 30 L = 1, N
                    177:             DO 20 K = M, 1, -1
                    178: *
                    179:                SUML = ZDOTU( M-K, A( K, MIN( K+1, M ) ), LDA,
                    180:      $                C( MIN( K+1, M ), L ), 1 )
                    181:                SUMR = ZDOTU( L-1, C( K, 1 ), LDC, B( 1, L ), 1 )
                    182:                VEC = C( K, L ) - ( SUML+SGN*SUMR )
                    183: *
                    184:                SCALOC = ONE
                    185:                A11 = A( K, K ) + SGN*B( L, L )
                    186:                DA11 = ABS( DBLE( A11 ) ) + ABS( DIMAG( A11 ) )
                    187:                IF( DA11.LE.SMIN ) THEN
                    188:                   A11 = SMIN
                    189:                   DA11 = SMIN
                    190:                   INFO = 1
                    191:                END IF
                    192:                DB = ABS( DBLE( VEC ) ) + ABS( DIMAG( VEC ) )
                    193:                IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
                    194:                   IF( DB.GT.BIGNUM*DA11 )
                    195:      $               SCALOC = ONE / DB
                    196:                END IF
                    197:                X11 = ZLADIV( VEC*DCMPLX( SCALOC ), A11 )
                    198: *
                    199:                IF( SCALOC.NE.ONE ) THEN
                    200:                   DO 10 J = 1, N
                    201:                      CALL ZDSCAL( M, SCALOC, C( 1, J ), 1 )
                    202:    10             CONTINUE
                    203:                   SCALE = SCALE*SCALOC
                    204:                END IF
                    205:                C( K, L ) = X11
                    206: *
                    207:    20       CONTINUE
                    208:    30    CONTINUE
                    209: *
                    210:       ELSE IF( .NOT.NOTRNA .AND. NOTRNB ) THEN
                    211: *
                    212: *        Solve    A' *X + ISGN*X*B = scale*C.
                    213: *
                    214: *        The (K,L)th block of X is determined starting from
                    215: *        upper-left corner column by column by
                    216: *
                    217: *            A'(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
                    218: *
                    219: *        Where
                    220: *                   K-1                         L-1
                    221: *          R(K,L) = SUM [A'(I,K)*X(I,L)] + ISGN*SUM [X(K,J)*B(J,L)]
                    222: *                   I=1                         J=1
                    223: *
                    224:          DO 60 L = 1, N
                    225:             DO 50 K = 1, M
                    226: *
                    227:                SUML = ZDOTC( K-1, A( 1, K ), 1, C( 1, L ), 1 )
                    228:                SUMR = ZDOTU( L-1, C( K, 1 ), LDC, B( 1, L ), 1 )
                    229:                VEC = C( K, L ) - ( SUML+SGN*SUMR )
                    230: *
                    231:                SCALOC = ONE
                    232:                A11 = DCONJG( A( K, K ) ) + SGN*B( L, L )
                    233:                DA11 = ABS( DBLE( A11 ) ) + ABS( DIMAG( A11 ) )
                    234:                IF( DA11.LE.SMIN ) THEN
                    235:                   A11 = SMIN
                    236:                   DA11 = SMIN
                    237:                   INFO = 1
                    238:                END IF
                    239:                DB = ABS( DBLE( VEC ) ) + ABS( DIMAG( VEC ) )
                    240:                IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
                    241:                   IF( DB.GT.BIGNUM*DA11 )
                    242:      $               SCALOC = ONE / DB
                    243:                END IF
                    244: *
                    245:                X11 = ZLADIV( VEC*DCMPLX( SCALOC ), A11 )
                    246: *
                    247:                IF( SCALOC.NE.ONE ) THEN
                    248:                   DO 40 J = 1, N
                    249:                      CALL ZDSCAL( M, SCALOC, C( 1, J ), 1 )
                    250:    40             CONTINUE
                    251:                   SCALE = SCALE*SCALOC
                    252:                END IF
                    253:                C( K, L ) = X11
                    254: *
                    255:    50       CONTINUE
                    256:    60    CONTINUE
                    257: *
                    258:       ELSE IF( .NOT.NOTRNA .AND. .NOT.NOTRNB ) THEN
                    259: *
                    260: *        Solve    A'*X + ISGN*X*B' = C.
                    261: *
                    262: *        The (K,L)th block of X is determined starting from
                    263: *        upper-right corner column by column by
                    264: *
                    265: *            A'(K,K)*X(K,L) + ISGN*X(K,L)*B'(L,L) = C(K,L) - R(K,L)
                    266: *
                    267: *        Where
                    268: *                    K-1
                    269: *           R(K,L) = SUM [A'(I,K)*X(I,L)] +
                    270: *                    I=1
                    271: *                           N
                    272: *                     ISGN*SUM [X(K,J)*B'(L,J)].
                    273: *                          J=L+1
                    274: *
                    275:          DO 90 L = N, 1, -1
                    276:             DO 80 K = 1, M
                    277: *
                    278:                SUML = ZDOTC( K-1, A( 1, K ), 1, C( 1, L ), 1 )
                    279:                SUMR = ZDOTC( N-L, C( K, MIN( L+1, N ) ), LDC,
                    280:      $                B( L, MIN( L+1, N ) ), LDB )
                    281:                VEC = C( K, L ) - ( SUML+SGN*DCONJG( SUMR ) )
                    282: *
                    283:                SCALOC = ONE
                    284:                A11 = DCONJG( A( K, K )+SGN*B( L, L ) )
                    285:                DA11 = ABS( DBLE( A11 ) ) + ABS( DIMAG( A11 ) )
                    286:                IF( DA11.LE.SMIN ) THEN
                    287:                   A11 = SMIN
                    288:                   DA11 = SMIN
                    289:                   INFO = 1
                    290:                END IF
                    291:                DB = ABS( DBLE( VEC ) ) + ABS( DIMAG( VEC ) )
                    292:                IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
                    293:                   IF( DB.GT.BIGNUM*DA11 )
                    294:      $               SCALOC = ONE / DB
                    295:                END IF
                    296: *
                    297:                X11 = ZLADIV( VEC*DCMPLX( SCALOC ), A11 )
                    298: *
                    299:                IF( SCALOC.NE.ONE ) THEN
                    300:                   DO 70 J = 1, N
                    301:                      CALL ZDSCAL( M, SCALOC, C( 1, J ), 1 )
                    302:    70             CONTINUE
                    303:                   SCALE = SCALE*SCALOC
                    304:                END IF
                    305:                C( K, L ) = X11
                    306: *
                    307:    80       CONTINUE
                    308:    90    CONTINUE
                    309: *
                    310:       ELSE IF( NOTRNA .AND. .NOT.NOTRNB ) THEN
                    311: *
                    312: *        Solve    A*X + ISGN*X*B' = C.
                    313: *
                    314: *        The (K,L)th block of X is determined starting from
                    315: *        bottom-left corner column by column by
                    316: *
                    317: *           A(K,K)*X(K,L) + ISGN*X(K,L)*B'(L,L) = C(K,L) - R(K,L)
                    318: *
                    319: *        Where
                    320: *                    M                          N
                    321: *          R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B'(L,J)]
                    322: *                  I=K+1                      J=L+1
                    323: *
                    324:          DO 120 L = N, 1, -1
                    325:             DO 110 K = M, 1, -1
                    326: *
                    327:                SUML = ZDOTU( M-K, A( K, MIN( K+1, M ) ), LDA,
                    328:      $                C( MIN( K+1, M ), L ), 1 )
                    329:                SUMR = ZDOTC( N-L, C( K, MIN( L+1, N ) ), LDC,
                    330:      $                B( L, MIN( L+1, N ) ), LDB )
                    331:                VEC = C( K, L ) - ( SUML+SGN*DCONJG( SUMR ) )
                    332: *
                    333:                SCALOC = ONE
                    334:                A11 = A( K, K ) + SGN*DCONJG( B( L, L ) )
                    335:                DA11 = ABS( DBLE( A11 ) ) + ABS( DIMAG( A11 ) )
                    336:                IF( DA11.LE.SMIN ) THEN
                    337:                   A11 = SMIN
                    338:                   DA11 = SMIN
                    339:                   INFO = 1
                    340:                END IF
                    341:                DB = ABS( DBLE( VEC ) ) + ABS( DIMAG( VEC ) )
                    342:                IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
                    343:                   IF( DB.GT.BIGNUM*DA11 )
                    344:      $               SCALOC = ONE / DB
                    345:                END IF
                    346: *
                    347:                X11 = ZLADIV( VEC*DCMPLX( SCALOC ), A11 )
                    348: *
                    349:                IF( SCALOC.NE.ONE ) THEN
                    350:                   DO 100 J = 1, N
                    351:                      CALL ZDSCAL( M, SCALOC, C( 1, J ), 1 )
                    352:   100             CONTINUE
                    353:                   SCALE = SCALE*SCALOC
                    354:                END IF
                    355:                C( K, L ) = X11
                    356: *
                    357:   110       CONTINUE
                    358:   120    CONTINUE
                    359: *
                    360:       END IF
                    361: *
                    362:       RETURN
                    363: *
                    364: *     End of ZTRSYL
                    365: *
                    366:       END

CVSweb interface <joel.bertrand@systella.fr>