Annotation of rpl/lapack/lapack/ztrsyl.f, revision 1.1
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>