Annotation of rpl/lapack/lapack/dtgsy2.f, revision 1.1
1.1 ! bertrand 1: SUBROUTINE DTGSY2( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D,
! 2: $ LDD, E, LDE, F, LDF, SCALE, RDSUM, RDSCAL,
! 3: $ IWORK, PQ, INFO )
! 4: *
! 5: * -- LAPACK auxiliary routine (version 3.2) --
! 6: * -- LAPACK is a software package provided by Univ. of Tennessee, --
! 7: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
! 8: * January 2007
! 9: *
! 10: * .. Scalar Arguments ..
! 11: CHARACTER TRANS
! 12: INTEGER IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF, M, N,
! 13: $ PQ
! 14: DOUBLE PRECISION RDSCAL, RDSUM, SCALE
! 15: * ..
! 16: * .. Array Arguments ..
! 17: INTEGER IWORK( * )
! 18: DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ),
! 19: $ D( LDD, * ), E( LDE, * ), F( LDF, * )
! 20: * ..
! 21: *
! 22: * Purpose
! 23: * =======
! 24: *
! 25: * DTGSY2 solves the generalized Sylvester equation:
! 26: *
! 27: * A * R - L * B = scale * C (1)
! 28: * D * R - L * E = scale * F,
! 29: *
! 30: * using Level 1 and 2 BLAS. where R and L are unknown M-by-N matrices,
! 31: * (A, D), (B, E) and (C, F) are given matrix pairs of size M-by-M,
! 32: * N-by-N and M-by-N, respectively, with real entries. (A, D) and (B, E)
! 33: * must be in generalized Schur canonical form, i.e. A, B are upper
! 34: * quasi triangular and D, E are upper triangular. The solution (R, L)
! 35: * overwrites (C, F). 0 <= SCALE <= 1 is an output scaling factor
! 36: * chosen to avoid overflow.
! 37: *
! 38: * In matrix notation solving equation (1) corresponds to solve
! 39: * Z*x = scale*b, where Z is defined as
! 40: *
! 41: * Z = [ kron(In, A) -kron(B', Im) ] (2)
! 42: * [ kron(In, D) -kron(E', Im) ],
! 43: *
! 44: * Ik is the identity matrix of size k and X' is the transpose of X.
! 45: * kron(X, Y) is the Kronecker product between the matrices X and Y.
! 46: * In the process of solving (1), we solve a number of such systems
! 47: * where Dim(In), Dim(In) = 1 or 2.
! 48: *
! 49: * If TRANS = 'T', solve the transposed system Z'*y = scale*b for y,
! 50: * which is equivalent to solve for R and L in
! 51: *
! 52: * A' * R + D' * L = scale * C (3)
! 53: * R * B' + L * E' = scale * -F
! 54: *
! 55: * This case is used to compute an estimate of Dif[(A, D), (B, E)] =
! 56: * sigma_min(Z) using reverse communicaton with DLACON.
! 57: *
! 58: * DTGSY2 also (IJOB >= 1) contributes to the computation in DTGSYL
! 59: * of an upper bound on the separation between to matrix pairs. Then
! 60: * the input (A, D), (B, E) are sub-pencils of the matrix pair in
! 61: * DTGSYL. See DTGSYL for details.
! 62: *
! 63: * Arguments
! 64: * =========
! 65: *
! 66: * TRANS (input) CHARACTER*1
! 67: * = 'N', solve the generalized Sylvester equation (1).
! 68: * = 'T': solve the 'transposed' system (3).
! 69: *
! 70: * IJOB (input) INTEGER
! 71: * Specifies what kind of functionality to be performed.
! 72: * = 0: solve (1) only.
! 73: * = 1: A contribution from this subsystem to a Frobenius
! 74: * norm-based estimate of the separation between two matrix
! 75: * pairs is computed. (look ahead strategy is used).
! 76: * = 2: A contribution from this subsystem to a Frobenius
! 77: * norm-based estimate of the separation between two matrix
! 78: * pairs is computed. (DGECON on sub-systems is used.)
! 79: * Not referenced if TRANS = 'T'.
! 80: *
! 81: * M (input) INTEGER
! 82: * On entry, M specifies the order of A and D, and the row
! 83: * dimension of C, F, R and L.
! 84: *
! 85: * N (input) INTEGER
! 86: * On entry, N specifies the order of B and E, and the column
! 87: * dimension of C, F, R and L.
! 88: *
! 89: * A (input) DOUBLE PRECISION array, dimension (LDA, M)
! 90: * On entry, A contains an upper quasi triangular matrix.
! 91: *
! 92: * LDA (input) INTEGER
! 93: * The leading dimension of the matrix A. LDA >= max(1, M).
! 94: *
! 95: * B (input) DOUBLE PRECISION array, dimension (LDB, N)
! 96: * On entry, B contains an upper quasi triangular matrix.
! 97: *
! 98: * LDB (input) INTEGER
! 99: * The leading dimension of the matrix B. LDB >= max(1, N).
! 100: *
! 101: * C (input/output) DOUBLE PRECISION array, dimension (LDC, N)
! 102: * On entry, C contains the right-hand-side of the first matrix
! 103: * equation in (1).
! 104: * On exit, if IJOB = 0, C has been overwritten by the
! 105: * solution R.
! 106: *
! 107: * LDC (input) INTEGER
! 108: * The leading dimension of the matrix C. LDC >= max(1, M).
! 109: *
! 110: * D (input) DOUBLE PRECISION array, dimension (LDD, M)
! 111: * On entry, D contains an upper triangular matrix.
! 112: *
! 113: * LDD (input) INTEGER
! 114: * The leading dimension of the matrix D. LDD >= max(1, M).
! 115: *
! 116: * E (input) DOUBLE PRECISION array, dimension (LDE, N)
! 117: * On entry, E contains an upper triangular matrix.
! 118: *
! 119: * LDE (input) INTEGER
! 120: * The leading dimension of the matrix E. LDE >= max(1, N).
! 121: *
! 122: * F (input/output) DOUBLE PRECISION array, dimension (LDF, N)
! 123: * On entry, F contains the right-hand-side of the second matrix
! 124: * equation in (1).
! 125: * On exit, if IJOB = 0, F has been overwritten by the
! 126: * solution L.
! 127: *
! 128: * LDF (input) INTEGER
! 129: * The leading dimension of the matrix F. LDF >= max(1, M).
! 130: *
! 131: * SCALE (output) DOUBLE PRECISION
! 132: * On exit, 0 <= SCALE <= 1. If 0 < SCALE < 1, the solutions
! 133: * R and L (C and F on entry) will hold the solutions to a
! 134: * slightly perturbed system but the input matrices A, B, D and
! 135: * E have not been changed. If SCALE = 0, R and L will hold the
! 136: * solutions to the homogeneous system with C = F = 0. Normally,
! 137: * SCALE = 1.
! 138: *
! 139: * RDSUM (input/output) DOUBLE PRECISION
! 140: * On entry, the sum of squares of computed contributions to
! 141: * the Dif-estimate under computation by DTGSYL, where the
! 142: * scaling factor RDSCAL (see below) has been factored out.
! 143: * On exit, the corresponding sum of squares updated with the
! 144: * contributions from the current sub-system.
! 145: * If TRANS = 'T' RDSUM is not touched.
! 146: * NOTE: RDSUM only makes sense when DTGSY2 is called by DTGSYL.
! 147: *
! 148: * RDSCAL (input/output) DOUBLE PRECISION
! 149: * On entry, scaling factor used to prevent overflow in RDSUM.
! 150: * On exit, RDSCAL is updated w.r.t. the current contributions
! 151: * in RDSUM.
! 152: * If TRANS = 'T', RDSCAL is not touched.
! 153: * NOTE: RDSCAL only makes sense when DTGSY2 is called by
! 154: * DTGSYL.
! 155: *
! 156: * IWORK (workspace) INTEGER array, dimension (M+N+2)
! 157: *
! 158: * PQ (output) INTEGER
! 159: * On exit, the number of subsystems (of size 2-by-2, 4-by-4 and
! 160: * 8-by-8) solved by this routine.
! 161: *
! 162: * INFO (output) INTEGER
! 163: * On exit, if INFO is set to
! 164: * =0: Successful exit
! 165: * <0: If INFO = -i, the i-th argument had an illegal value.
! 166: * >0: The matrix pairs (A, D) and (B, E) have common or very
! 167: * close eigenvalues.
! 168: *
! 169: * Further Details
! 170: * ===============
! 171: *
! 172: * Based on contributions by
! 173: * Bo Kagstrom and Peter Poromaa, Department of Computing Science,
! 174: * Umea University, S-901 87 Umea, Sweden.
! 175: *
! 176: * =====================================================================
! 177: * Replaced various illegal calls to DCOPY by calls to DLASET.
! 178: * Sven Hammarling, 27/5/02.
! 179: *
! 180: * .. Parameters ..
! 181: INTEGER LDZ
! 182: PARAMETER ( LDZ = 8 )
! 183: DOUBLE PRECISION ZERO, ONE
! 184: PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
! 185: * ..
! 186: * .. Local Scalars ..
! 187: LOGICAL NOTRAN
! 188: INTEGER I, IE, IERR, II, IS, ISP1, J, JE, JJ, JS, JSP1,
! 189: $ K, MB, NB, P, Q, ZDIM
! 190: DOUBLE PRECISION ALPHA, SCALOC
! 191: * ..
! 192: * .. Local Arrays ..
! 193: INTEGER IPIV( LDZ ), JPIV( LDZ )
! 194: DOUBLE PRECISION RHS( LDZ ), Z( LDZ, LDZ )
! 195: * ..
! 196: * .. External Functions ..
! 197: LOGICAL LSAME
! 198: EXTERNAL LSAME
! 199: * ..
! 200: * .. External Subroutines ..
! 201: EXTERNAL DAXPY, DCOPY, DGEMM, DGEMV, DGER, DGESC2,
! 202: $ DGETC2, DLASET, DLATDF, DSCAL, XERBLA
! 203: * ..
! 204: * .. Intrinsic Functions ..
! 205: INTRINSIC MAX
! 206: * ..
! 207: * .. Executable Statements ..
! 208: *
! 209: * Decode and test input parameters
! 210: *
! 211: INFO = 0
! 212: IERR = 0
! 213: NOTRAN = LSAME( TRANS, 'N' )
! 214: IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
! 215: INFO = -1
! 216: ELSE IF( NOTRAN ) THEN
! 217: IF( ( IJOB.LT.0 ) .OR. ( IJOB.GT.2 ) ) THEN
! 218: INFO = -2
! 219: END IF
! 220: END IF
! 221: IF( INFO.EQ.0 ) THEN
! 222: IF( M.LE.0 ) THEN
! 223: INFO = -3
! 224: ELSE IF( N.LE.0 ) THEN
! 225: INFO = -4
! 226: ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
! 227: INFO = -5
! 228: ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
! 229: INFO = -8
! 230: ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
! 231: INFO = -10
! 232: ELSE IF( LDD.LT.MAX( 1, M ) ) THEN
! 233: INFO = -12
! 234: ELSE IF( LDE.LT.MAX( 1, N ) ) THEN
! 235: INFO = -14
! 236: ELSE IF( LDF.LT.MAX( 1, M ) ) THEN
! 237: INFO = -16
! 238: END IF
! 239: END IF
! 240: IF( INFO.NE.0 ) THEN
! 241: CALL XERBLA( 'DTGSY2', -INFO )
! 242: RETURN
! 243: END IF
! 244: *
! 245: * Determine block structure of A
! 246: *
! 247: PQ = 0
! 248: P = 0
! 249: I = 1
! 250: 10 CONTINUE
! 251: IF( I.GT.M )
! 252: $ GO TO 20
! 253: P = P + 1
! 254: IWORK( P ) = I
! 255: IF( I.EQ.M )
! 256: $ GO TO 20
! 257: IF( A( I+1, I ).NE.ZERO ) THEN
! 258: I = I + 2
! 259: ELSE
! 260: I = I + 1
! 261: END IF
! 262: GO TO 10
! 263: 20 CONTINUE
! 264: IWORK( P+1 ) = M + 1
! 265: *
! 266: * Determine block structure of B
! 267: *
! 268: Q = P + 1
! 269: J = 1
! 270: 30 CONTINUE
! 271: IF( J.GT.N )
! 272: $ GO TO 40
! 273: Q = Q + 1
! 274: IWORK( Q ) = J
! 275: IF( J.EQ.N )
! 276: $ GO TO 40
! 277: IF( B( J+1, J ).NE.ZERO ) THEN
! 278: J = J + 2
! 279: ELSE
! 280: J = J + 1
! 281: END IF
! 282: GO TO 30
! 283: 40 CONTINUE
! 284: IWORK( Q+1 ) = N + 1
! 285: PQ = P*( Q-P-1 )
! 286: *
! 287: IF( NOTRAN ) THEN
! 288: *
! 289: * Solve (I, J) - subsystem
! 290: * A(I, I) * R(I, J) - L(I, J) * B(J, J) = C(I, J)
! 291: * D(I, I) * R(I, J) - L(I, J) * E(J, J) = F(I, J)
! 292: * for I = P, P - 1, ..., 1; J = 1, 2, ..., Q
! 293: *
! 294: SCALE = ONE
! 295: SCALOC = ONE
! 296: DO 120 J = P + 2, Q
! 297: JS = IWORK( J )
! 298: JSP1 = JS + 1
! 299: JE = IWORK( J+1 ) - 1
! 300: NB = JE - JS + 1
! 301: DO 110 I = P, 1, -1
! 302: *
! 303: IS = IWORK( I )
! 304: ISP1 = IS + 1
! 305: IE = IWORK( I+1 ) - 1
! 306: MB = IE - IS + 1
! 307: ZDIM = MB*NB*2
! 308: *
! 309: IF( ( MB.EQ.1 ) .AND. ( NB.EQ.1 ) ) THEN
! 310: *
! 311: * Build a 2-by-2 system Z * x = RHS
! 312: *
! 313: Z( 1, 1 ) = A( IS, IS )
! 314: Z( 2, 1 ) = D( IS, IS )
! 315: Z( 1, 2 ) = -B( JS, JS )
! 316: Z( 2, 2 ) = -E( JS, JS )
! 317: *
! 318: * Set up right hand side(s)
! 319: *
! 320: RHS( 1 ) = C( IS, JS )
! 321: RHS( 2 ) = F( IS, JS )
! 322: *
! 323: * Solve Z * x = RHS
! 324: *
! 325: CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )
! 326: IF( IERR.GT.0 )
! 327: $ INFO = IERR
! 328: *
! 329: IF( IJOB.EQ.0 ) THEN
! 330: CALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV,
! 331: $ SCALOC )
! 332: IF( SCALOC.NE.ONE ) THEN
! 333: DO 50 K = 1, N
! 334: CALL DSCAL( M, SCALOC, C( 1, K ), 1 )
! 335: CALL DSCAL( M, SCALOC, F( 1, K ), 1 )
! 336: 50 CONTINUE
! 337: SCALE = SCALE*SCALOC
! 338: END IF
! 339: ELSE
! 340: CALL DLATDF( IJOB, ZDIM, Z, LDZ, RHS, RDSUM,
! 341: $ RDSCAL, IPIV, JPIV )
! 342: END IF
! 343: *
! 344: * Unpack solution vector(s)
! 345: *
! 346: C( IS, JS ) = RHS( 1 )
! 347: F( IS, JS ) = RHS( 2 )
! 348: *
! 349: * Substitute R(I, J) and L(I, J) into remaining
! 350: * equation.
! 351: *
! 352: IF( I.GT.1 ) THEN
! 353: ALPHA = -RHS( 1 )
! 354: CALL DAXPY( IS-1, ALPHA, A( 1, IS ), 1, C( 1, JS ),
! 355: $ 1 )
! 356: CALL DAXPY( IS-1, ALPHA, D( 1, IS ), 1, F( 1, JS ),
! 357: $ 1 )
! 358: END IF
! 359: IF( J.LT.Q ) THEN
! 360: CALL DAXPY( N-JE, RHS( 2 ), B( JS, JE+1 ), LDB,
! 361: $ C( IS, JE+1 ), LDC )
! 362: CALL DAXPY( N-JE, RHS( 2 ), E( JS, JE+1 ), LDE,
! 363: $ F( IS, JE+1 ), LDF )
! 364: END IF
! 365: *
! 366: ELSE IF( ( MB.EQ.1 ) .AND. ( NB.EQ.2 ) ) THEN
! 367: *
! 368: * Build a 4-by-4 system Z * x = RHS
! 369: *
! 370: Z( 1, 1 ) = A( IS, IS )
! 371: Z( 2, 1 ) = ZERO
! 372: Z( 3, 1 ) = D( IS, IS )
! 373: Z( 4, 1 ) = ZERO
! 374: *
! 375: Z( 1, 2 ) = ZERO
! 376: Z( 2, 2 ) = A( IS, IS )
! 377: Z( 3, 2 ) = ZERO
! 378: Z( 4, 2 ) = D( IS, IS )
! 379: *
! 380: Z( 1, 3 ) = -B( JS, JS )
! 381: Z( 2, 3 ) = -B( JS, JSP1 )
! 382: Z( 3, 3 ) = -E( JS, JS )
! 383: Z( 4, 3 ) = -E( JS, JSP1 )
! 384: *
! 385: Z( 1, 4 ) = -B( JSP1, JS )
! 386: Z( 2, 4 ) = -B( JSP1, JSP1 )
! 387: Z( 3, 4 ) = ZERO
! 388: Z( 4, 4 ) = -E( JSP1, JSP1 )
! 389: *
! 390: * Set up right hand side(s)
! 391: *
! 392: RHS( 1 ) = C( IS, JS )
! 393: RHS( 2 ) = C( IS, JSP1 )
! 394: RHS( 3 ) = F( IS, JS )
! 395: RHS( 4 ) = F( IS, JSP1 )
! 396: *
! 397: * Solve Z * x = RHS
! 398: *
! 399: CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )
! 400: IF( IERR.GT.0 )
! 401: $ INFO = IERR
! 402: *
! 403: IF( IJOB.EQ.0 ) THEN
! 404: CALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV,
! 405: $ SCALOC )
! 406: IF( SCALOC.NE.ONE ) THEN
! 407: DO 60 K = 1, N
! 408: CALL DSCAL( M, SCALOC, C( 1, K ), 1 )
! 409: CALL DSCAL( M, SCALOC, F( 1, K ), 1 )
! 410: 60 CONTINUE
! 411: SCALE = SCALE*SCALOC
! 412: END IF
! 413: ELSE
! 414: CALL DLATDF( IJOB, ZDIM, Z, LDZ, RHS, RDSUM,
! 415: $ RDSCAL, IPIV, JPIV )
! 416: END IF
! 417: *
! 418: * Unpack solution vector(s)
! 419: *
! 420: C( IS, JS ) = RHS( 1 )
! 421: C( IS, JSP1 ) = RHS( 2 )
! 422: F( IS, JS ) = RHS( 3 )
! 423: F( IS, JSP1 ) = RHS( 4 )
! 424: *
! 425: * Substitute R(I, J) and L(I, J) into remaining
! 426: * equation.
! 427: *
! 428: IF( I.GT.1 ) THEN
! 429: CALL DGER( IS-1, NB, -ONE, A( 1, IS ), 1, RHS( 1 ),
! 430: $ 1, C( 1, JS ), LDC )
! 431: CALL DGER( IS-1, NB, -ONE, D( 1, IS ), 1, RHS( 1 ),
! 432: $ 1, F( 1, JS ), LDF )
! 433: END IF
! 434: IF( J.LT.Q ) THEN
! 435: CALL DAXPY( N-JE, RHS( 3 ), B( JS, JE+1 ), LDB,
! 436: $ C( IS, JE+1 ), LDC )
! 437: CALL DAXPY( N-JE, RHS( 3 ), E( JS, JE+1 ), LDE,
! 438: $ F( IS, JE+1 ), LDF )
! 439: CALL DAXPY( N-JE, RHS( 4 ), B( JSP1, JE+1 ), LDB,
! 440: $ C( IS, JE+1 ), LDC )
! 441: CALL DAXPY( N-JE, RHS( 4 ), E( JSP1, JE+1 ), LDE,
! 442: $ F( IS, JE+1 ), LDF )
! 443: END IF
! 444: *
! 445: ELSE IF( ( MB.EQ.2 ) .AND. ( NB.EQ.1 ) ) THEN
! 446: *
! 447: * Build a 4-by-4 system Z * x = RHS
! 448: *
! 449: Z( 1, 1 ) = A( IS, IS )
! 450: Z( 2, 1 ) = A( ISP1, IS )
! 451: Z( 3, 1 ) = D( IS, IS )
! 452: Z( 4, 1 ) = ZERO
! 453: *
! 454: Z( 1, 2 ) = A( IS, ISP1 )
! 455: Z( 2, 2 ) = A( ISP1, ISP1 )
! 456: Z( 3, 2 ) = D( IS, ISP1 )
! 457: Z( 4, 2 ) = D( ISP1, ISP1 )
! 458: *
! 459: Z( 1, 3 ) = -B( JS, JS )
! 460: Z( 2, 3 ) = ZERO
! 461: Z( 3, 3 ) = -E( JS, JS )
! 462: Z( 4, 3 ) = ZERO
! 463: *
! 464: Z( 1, 4 ) = ZERO
! 465: Z( 2, 4 ) = -B( JS, JS )
! 466: Z( 3, 4 ) = ZERO
! 467: Z( 4, 4 ) = -E( JS, JS )
! 468: *
! 469: * Set up right hand side(s)
! 470: *
! 471: RHS( 1 ) = C( IS, JS )
! 472: RHS( 2 ) = C( ISP1, JS )
! 473: RHS( 3 ) = F( IS, JS )
! 474: RHS( 4 ) = F( ISP1, JS )
! 475: *
! 476: * Solve Z * x = RHS
! 477: *
! 478: CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )
! 479: IF( IERR.GT.0 )
! 480: $ INFO = IERR
! 481: IF( IJOB.EQ.0 ) THEN
! 482: CALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV,
! 483: $ SCALOC )
! 484: IF( SCALOC.NE.ONE ) THEN
! 485: DO 70 K = 1, N
! 486: CALL DSCAL( M, SCALOC, C( 1, K ), 1 )
! 487: CALL DSCAL( M, SCALOC, F( 1, K ), 1 )
! 488: 70 CONTINUE
! 489: SCALE = SCALE*SCALOC
! 490: END IF
! 491: ELSE
! 492: CALL DLATDF( IJOB, ZDIM, Z, LDZ, RHS, RDSUM,
! 493: $ RDSCAL, IPIV, JPIV )
! 494: END IF
! 495: *
! 496: * Unpack solution vector(s)
! 497: *
! 498: C( IS, JS ) = RHS( 1 )
! 499: C( ISP1, JS ) = RHS( 2 )
! 500: F( IS, JS ) = RHS( 3 )
! 501: F( ISP1, JS ) = RHS( 4 )
! 502: *
! 503: * Substitute R(I, J) and L(I, J) into remaining
! 504: * equation.
! 505: *
! 506: IF( I.GT.1 ) THEN
! 507: CALL DGEMV( 'N', IS-1, MB, -ONE, A( 1, IS ), LDA,
! 508: $ RHS( 1 ), 1, ONE, C( 1, JS ), 1 )
! 509: CALL DGEMV( 'N', IS-1, MB, -ONE, D( 1, IS ), LDD,
! 510: $ RHS( 1 ), 1, ONE, F( 1, JS ), 1 )
! 511: END IF
! 512: IF( J.LT.Q ) THEN
! 513: CALL DGER( MB, N-JE, ONE, RHS( 3 ), 1,
! 514: $ B( JS, JE+1 ), LDB, C( IS, JE+1 ), LDC )
! 515: CALL DGER( MB, N-JE, ONE, RHS( 3 ), 1,
! 516: $ E( JS, JE+1 ), LDE, F( IS, JE+1 ), LDF )
! 517: END IF
! 518: *
! 519: ELSE IF( ( MB.EQ.2 ) .AND. ( NB.EQ.2 ) ) THEN
! 520: *
! 521: * Build an 8-by-8 system Z * x = RHS
! 522: *
! 523: CALL DLASET( 'F', LDZ, LDZ, ZERO, ZERO, Z, LDZ )
! 524: *
! 525: Z( 1, 1 ) = A( IS, IS )
! 526: Z( 2, 1 ) = A( ISP1, IS )
! 527: Z( 5, 1 ) = D( IS, IS )
! 528: *
! 529: Z( 1, 2 ) = A( IS, ISP1 )
! 530: Z( 2, 2 ) = A( ISP1, ISP1 )
! 531: Z( 5, 2 ) = D( IS, ISP1 )
! 532: Z( 6, 2 ) = D( ISP1, ISP1 )
! 533: *
! 534: Z( 3, 3 ) = A( IS, IS )
! 535: Z( 4, 3 ) = A( ISP1, IS )
! 536: Z( 7, 3 ) = D( IS, IS )
! 537: *
! 538: Z( 3, 4 ) = A( IS, ISP1 )
! 539: Z( 4, 4 ) = A( ISP1, ISP1 )
! 540: Z( 7, 4 ) = D( IS, ISP1 )
! 541: Z( 8, 4 ) = D( ISP1, ISP1 )
! 542: *
! 543: Z( 1, 5 ) = -B( JS, JS )
! 544: Z( 3, 5 ) = -B( JS, JSP1 )
! 545: Z( 5, 5 ) = -E( JS, JS )
! 546: Z( 7, 5 ) = -E( JS, JSP1 )
! 547: *
! 548: Z( 2, 6 ) = -B( JS, JS )
! 549: Z( 4, 6 ) = -B( JS, JSP1 )
! 550: Z( 6, 6 ) = -E( JS, JS )
! 551: Z( 8, 6 ) = -E( JS, JSP1 )
! 552: *
! 553: Z( 1, 7 ) = -B( JSP1, JS )
! 554: Z( 3, 7 ) = -B( JSP1, JSP1 )
! 555: Z( 7, 7 ) = -E( JSP1, JSP1 )
! 556: *
! 557: Z( 2, 8 ) = -B( JSP1, JS )
! 558: Z( 4, 8 ) = -B( JSP1, JSP1 )
! 559: Z( 8, 8 ) = -E( JSP1, JSP1 )
! 560: *
! 561: * Set up right hand side(s)
! 562: *
! 563: K = 1
! 564: II = MB*NB + 1
! 565: DO 80 JJ = 0, NB - 1
! 566: CALL DCOPY( MB, C( IS, JS+JJ ), 1, RHS( K ), 1 )
! 567: CALL DCOPY( MB, F( IS, JS+JJ ), 1, RHS( II ), 1 )
! 568: K = K + MB
! 569: II = II + MB
! 570: 80 CONTINUE
! 571: *
! 572: * Solve Z * x = RHS
! 573: *
! 574: CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )
! 575: IF( IERR.GT.0 )
! 576: $ INFO = IERR
! 577: IF( IJOB.EQ.0 ) THEN
! 578: CALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV,
! 579: $ SCALOC )
! 580: IF( SCALOC.NE.ONE ) THEN
! 581: DO 90 K = 1, N
! 582: CALL DSCAL( M, SCALOC, C( 1, K ), 1 )
! 583: CALL DSCAL( M, SCALOC, F( 1, K ), 1 )
! 584: 90 CONTINUE
! 585: SCALE = SCALE*SCALOC
! 586: END IF
! 587: ELSE
! 588: CALL DLATDF( IJOB, ZDIM, Z, LDZ, RHS, RDSUM,
! 589: $ RDSCAL, IPIV, JPIV )
! 590: END IF
! 591: *
! 592: * Unpack solution vector(s)
! 593: *
! 594: K = 1
! 595: II = MB*NB + 1
! 596: DO 100 JJ = 0, NB - 1
! 597: CALL DCOPY( MB, RHS( K ), 1, C( IS, JS+JJ ), 1 )
! 598: CALL DCOPY( MB, RHS( II ), 1, F( IS, JS+JJ ), 1 )
! 599: K = K + MB
! 600: II = II + MB
! 601: 100 CONTINUE
! 602: *
! 603: * Substitute R(I, J) and L(I, J) into remaining
! 604: * equation.
! 605: *
! 606: IF( I.GT.1 ) THEN
! 607: CALL DGEMM( 'N', 'N', IS-1, NB, MB, -ONE,
! 608: $ A( 1, IS ), LDA, RHS( 1 ), MB, ONE,
! 609: $ C( 1, JS ), LDC )
! 610: CALL DGEMM( 'N', 'N', IS-1, NB, MB, -ONE,
! 611: $ D( 1, IS ), LDD, RHS( 1 ), MB, ONE,
! 612: $ F( 1, JS ), LDF )
! 613: END IF
! 614: IF( J.LT.Q ) THEN
! 615: K = MB*NB + 1
! 616: CALL DGEMM( 'N', 'N', MB, N-JE, NB, ONE, RHS( K ),
! 617: $ MB, B( JS, JE+1 ), LDB, ONE,
! 618: $ C( IS, JE+1 ), LDC )
! 619: CALL DGEMM( 'N', 'N', MB, N-JE, NB, ONE, RHS( K ),
! 620: $ MB, E( JS, JE+1 ), LDE, ONE,
! 621: $ F( IS, JE+1 ), LDF )
! 622: END IF
! 623: *
! 624: END IF
! 625: *
! 626: 110 CONTINUE
! 627: 120 CONTINUE
! 628: ELSE
! 629: *
! 630: * Solve (I, J) - subsystem
! 631: * A(I, I)' * R(I, J) + D(I, I)' * L(J, J) = C(I, J)
! 632: * R(I, I) * B(J, J) + L(I, J) * E(J, J) = -F(I, J)
! 633: * for I = 1, 2, ..., P, J = Q, Q - 1, ..., 1
! 634: *
! 635: SCALE = ONE
! 636: SCALOC = ONE
! 637: DO 200 I = 1, P
! 638: *
! 639: IS = IWORK( I )
! 640: ISP1 = IS + 1
! 641: IE = ( I+1 ) - 1
! 642: MB = IE - IS + 1
! 643: DO 190 J = Q, P + 2, -1
! 644: *
! 645: JS = IWORK( J )
! 646: JSP1 = JS + 1
! 647: JE = IWORK( J+1 ) - 1
! 648: NB = JE - JS + 1
! 649: ZDIM = MB*NB*2
! 650: IF( ( MB.EQ.1 ) .AND. ( NB.EQ.1 ) ) THEN
! 651: *
! 652: * Build a 2-by-2 system Z' * x = RHS
! 653: *
! 654: Z( 1, 1 ) = A( IS, IS )
! 655: Z( 2, 1 ) = -B( JS, JS )
! 656: Z( 1, 2 ) = D( IS, IS )
! 657: Z( 2, 2 ) = -E( JS, JS )
! 658: *
! 659: * Set up right hand side(s)
! 660: *
! 661: RHS( 1 ) = C( IS, JS )
! 662: RHS( 2 ) = F( IS, JS )
! 663: *
! 664: * Solve Z' * x = RHS
! 665: *
! 666: CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )
! 667: IF( IERR.GT.0 )
! 668: $ INFO = IERR
! 669: *
! 670: CALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV, SCALOC )
! 671: IF( SCALOC.NE.ONE ) THEN
! 672: DO 130 K = 1, N
! 673: CALL DSCAL( M, SCALOC, C( 1, K ), 1 )
! 674: CALL DSCAL( M, SCALOC, F( 1, K ), 1 )
! 675: 130 CONTINUE
! 676: SCALE = SCALE*SCALOC
! 677: END IF
! 678: *
! 679: * Unpack solution vector(s)
! 680: *
! 681: C( IS, JS ) = RHS( 1 )
! 682: F( IS, JS ) = RHS( 2 )
! 683: *
! 684: * Substitute R(I, J) and L(I, J) into remaining
! 685: * equation.
! 686: *
! 687: IF( J.GT.P+2 ) THEN
! 688: ALPHA = RHS( 1 )
! 689: CALL DAXPY( JS-1, ALPHA, B( 1, JS ), 1, F( IS, 1 ),
! 690: $ LDF )
! 691: ALPHA = RHS( 2 )
! 692: CALL DAXPY( JS-1, ALPHA, E( 1, JS ), 1, F( IS, 1 ),
! 693: $ LDF )
! 694: END IF
! 695: IF( I.LT.P ) THEN
! 696: ALPHA = -RHS( 1 )
! 697: CALL DAXPY( M-IE, ALPHA, A( IS, IE+1 ), LDA,
! 698: $ C( IE+1, JS ), 1 )
! 699: ALPHA = -RHS( 2 )
! 700: CALL DAXPY( M-IE, ALPHA, D( IS, IE+1 ), LDD,
! 701: $ C( IE+1, JS ), 1 )
! 702: END IF
! 703: *
! 704: ELSE IF( ( MB.EQ.1 ) .AND. ( NB.EQ.2 ) ) THEN
! 705: *
! 706: * Build a 4-by-4 system Z' * x = RHS
! 707: *
! 708: Z( 1, 1 ) = A( IS, IS )
! 709: Z( 2, 1 ) = ZERO
! 710: Z( 3, 1 ) = -B( JS, JS )
! 711: Z( 4, 1 ) = -B( JSP1, JS )
! 712: *
! 713: Z( 1, 2 ) = ZERO
! 714: Z( 2, 2 ) = A( IS, IS )
! 715: Z( 3, 2 ) = -B( JS, JSP1 )
! 716: Z( 4, 2 ) = -B( JSP1, JSP1 )
! 717: *
! 718: Z( 1, 3 ) = D( IS, IS )
! 719: Z( 2, 3 ) = ZERO
! 720: Z( 3, 3 ) = -E( JS, JS )
! 721: Z( 4, 3 ) = ZERO
! 722: *
! 723: Z( 1, 4 ) = ZERO
! 724: Z( 2, 4 ) = D( IS, IS )
! 725: Z( 3, 4 ) = -E( JS, JSP1 )
! 726: Z( 4, 4 ) = -E( JSP1, JSP1 )
! 727: *
! 728: * Set up right hand side(s)
! 729: *
! 730: RHS( 1 ) = C( IS, JS )
! 731: RHS( 2 ) = C( IS, JSP1 )
! 732: RHS( 3 ) = F( IS, JS )
! 733: RHS( 4 ) = F( IS, JSP1 )
! 734: *
! 735: * Solve Z' * x = RHS
! 736: *
! 737: CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )
! 738: IF( IERR.GT.0 )
! 739: $ INFO = IERR
! 740: CALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV, SCALOC )
! 741: IF( SCALOC.NE.ONE ) THEN
! 742: DO 140 K = 1, N
! 743: CALL DSCAL( M, SCALOC, C( 1, K ), 1 )
! 744: CALL DSCAL( M, SCALOC, F( 1, K ), 1 )
! 745: 140 CONTINUE
! 746: SCALE = SCALE*SCALOC
! 747: END IF
! 748: *
! 749: * Unpack solution vector(s)
! 750: *
! 751: C( IS, JS ) = RHS( 1 )
! 752: C( IS, JSP1 ) = RHS( 2 )
! 753: F( IS, JS ) = RHS( 3 )
! 754: F( IS, JSP1 ) = RHS( 4 )
! 755: *
! 756: * Substitute R(I, J) and L(I, J) into remaining
! 757: * equation.
! 758: *
! 759: IF( J.GT.P+2 ) THEN
! 760: CALL DAXPY( JS-1, RHS( 1 ), B( 1, JS ), 1,
! 761: $ F( IS, 1 ), LDF )
! 762: CALL DAXPY( JS-1, RHS( 2 ), B( 1, JSP1 ), 1,
! 763: $ F( IS, 1 ), LDF )
! 764: CALL DAXPY( JS-1, RHS( 3 ), E( 1, JS ), 1,
! 765: $ F( IS, 1 ), LDF )
! 766: CALL DAXPY( JS-1, RHS( 4 ), E( 1, JSP1 ), 1,
! 767: $ F( IS, 1 ), LDF )
! 768: END IF
! 769: IF( I.LT.P ) THEN
! 770: CALL DGER( M-IE, NB, -ONE, A( IS, IE+1 ), LDA,
! 771: $ RHS( 1 ), 1, C( IE+1, JS ), LDC )
! 772: CALL DGER( M-IE, NB, -ONE, D( IS, IE+1 ), LDD,
! 773: $ RHS( 3 ), 1, C( IE+1, JS ), LDC )
! 774: END IF
! 775: *
! 776: ELSE IF( ( MB.EQ.2 ) .AND. ( NB.EQ.1 ) ) THEN
! 777: *
! 778: * Build a 4-by-4 system Z' * x = RHS
! 779: *
! 780: Z( 1, 1 ) = A( IS, IS )
! 781: Z( 2, 1 ) = A( IS, ISP1 )
! 782: Z( 3, 1 ) = -B( JS, JS )
! 783: Z( 4, 1 ) = ZERO
! 784: *
! 785: Z( 1, 2 ) = A( ISP1, IS )
! 786: Z( 2, 2 ) = A( ISP1, ISP1 )
! 787: Z( 3, 2 ) = ZERO
! 788: Z( 4, 2 ) = -B( JS, JS )
! 789: *
! 790: Z( 1, 3 ) = D( IS, IS )
! 791: Z( 2, 3 ) = D( IS, ISP1 )
! 792: Z( 3, 3 ) = -E( JS, JS )
! 793: Z( 4, 3 ) = ZERO
! 794: *
! 795: Z( 1, 4 ) = ZERO
! 796: Z( 2, 4 ) = D( ISP1, ISP1 )
! 797: Z( 3, 4 ) = ZERO
! 798: Z( 4, 4 ) = -E( JS, JS )
! 799: *
! 800: * Set up right hand side(s)
! 801: *
! 802: RHS( 1 ) = C( IS, JS )
! 803: RHS( 2 ) = C( ISP1, JS )
! 804: RHS( 3 ) = F( IS, JS )
! 805: RHS( 4 ) = F( ISP1, JS )
! 806: *
! 807: * Solve Z' * x = RHS
! 808: *
! 809: CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )
! 810: IF( IERR.GT.0 )
! 811: $ INFO = IERR
! 812: *
! 813: CALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV, SCALOC )
! 814: IF( SCALOC.NE.ONE ) THEN
! 815: DO 150 K = 1, N
! 816: CALL DSCAL( M, SCALOC, C( 1, K ), 1 )
! 817: CALL DSCAL( M, SCALOC, F( 1, K ), 1 )
! 818: 150 CONTINUE
! 819: SCALE = SCALE*SCALOC
! 820: END IF
! 821: *
! 822: * Unpack solution vector(s)
! 823: *
! 824: C( IS, JS ) = RHS( 1 )
! 825: C( ISP1, JS ) = RHS( 2 )
! 826: F( IS, JS ) = RHS( 3 )
! 827: F( ISP1, JS ) = RHS( 4 )
! 828: *
! 829: * Substitute R(I, J) and L(I, J) into remaining
! 830: * equation.
! 831: *
! 832: IF( J.GT.P+2 ) THEN
! 833: CALL DGER( MB, JS-1, ONE, RHS( 1 ), 1, B( 1, JS ),
! 834: $ 1, F( IS, 1 ), LDF )
! 835: CALL DGER( MB, JS-1, ONE, RHS( 3 ), 1, E( 1, JS ),
! 836: $ 1, F( IS, 1 ), LDF )
! 837: END IF
! 838: IF( I.LT.P ) THEN
! 839: CALL DGEMV( 'T', MB, M-IE, -ONE, A( IS, IE+1 ),
! 840: $ LDA, RHS( 1 ), 1, ONE, C( IE+1, JS ),
! 841: $ 1 )
! 842: CALL DGEMV( 'T', MB, M-IE, -ONE, D( IS, IE+1 ),
! 843: $ LDD, RHS( 3 ), 1, ONE, C( IE+1, JS ),
! 844: $ 1 )
! 845: END IF
! 846: *
! 847: ELSE IF( ( MB.EQ.2 ) .AND. ( NB.EQ.2 ) ) THEN
! 848: *
! 849: * Build an 8-by-8 system Z' * x = RHS
! 850: *
! 851: CALL DLASET( 'F', LDZ, LDZ, ZERO, ZERO, Z, LDZ )
! 852: *
! 853: Z( 1, 1 ) = A( IS, IS )
! 854: Z( 2, 1 ) = A( IS, ISP1 )
! 855: Z( 5, 1 ) = -B( JS, JS )
! 856: Z( 7, 1 ) = -B( JSP1, JS )
! 857: *
! 858: Z( 1, 2 ) = A( ISP1, IS )
! 859: Z( 2, 2 ) = A( ISP1, ISP1 )
! 860: Z( 6, 2 ) = -B( JS, JS )
! 861: Z( 8, 2 ) = -B( JSP1, JS )
! 862: *
! 863: Z( 3, 3 ) = A( IS, IS )
! 864: Z( 4, 3 ) = A( IS, ISP1 )
! 865: Z( 5, 3 ) = -B( JS, JSP1 )
! 866: Z( 7, 3 ) = -B( JSP1, JSP1 )
! 867: *
! 868: Z( 3, 4 ) = A( ISP1, IS )
! 869: Z( 4, 4 ) = A( ISP1, ISP1 )
! 870: Z( 6, 4 ) = -B( JS, JSP1 )
! 871: Z( 8, 4 ) = -B( JSP1, JSP1 )
! 872: *
! 873: Z( 1, 5 ) = D( IS, IS )
! 874: Z( 2, 5 ) = D( IS, ISP1 )
! 875: Z( 5, 5 ) = -E( JS, JS )
! 876: *
! 877: Z( 2, 6 ) = D( ISP1, ISP1 )
! 878: Z( 6, 6 ) = -E( JS, JS )
! 879: *
! 880: Z( 3, 7 ) = D( IS, IS )
! 881: Z( 4, 7 ) = D( IS, ISP1 )
! 882: Z( 5, 7 ) = -E( JS, JSP1 )
! 883: Z( 7, 7 ) = -E( JSP1, JSP1 )
! 884: *
! 885: Z( 4, 8 ) = D( ISP1, ISP1 )
! 886: Z( 6, 8 ) = -E( JS, JSP1 )
! 887: Z( 8, 8 ) = -E( JSP1, JSP1 )
! 888: *
! 889: * Set up right hand side(s)
! 890: *
! 891: K = 1
! 892: II = MB*NB + 1
! 893: DO 160 JJ = 0, NB - 1
! 894: CALL DCOPY( MB, C( IS, JS+JJ ), 1, RHS( K ), 1 )
! 895: CALL DCOPY( MB, F( IS, JS+JJ ), 1, RHS( II ), 1 )
! 896: K = K + MB
! 897: II = II + MB
! 898: 160 CONTINUE
! 899: *
! 900: *
! 901: * Solve Z' * x = RHS
! 902: *
! 903: CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )
! 904: IF( IERR.GT.0 )
! 905: $ INFO = IERR
! 906: *
! 907: CALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV, SCALOC )
! 908: IF( SCALOC.NE.ONE ) THEN
! 909: DO 170 K = 1, N
! 910: CALL DSCAL( M, SCALOC, C( 1, K ), 1 )
! 911: CALL DSCAL( M, SCALOC, F( 1, K ), 1 )
! 912: 170 CONTINUE
! 913: SCALE = SCALE*SCALOC
! 914: END IF
! 915: *
! 916: * Unpack solution vector(s)
! 917: *
! 918: K = 1
! 919: II = MB*NB + 1
! 920: DO 180 JJ = 0, NB - 1
! 921: CALL DCOPY( MB, RHS( K ), 1, C( IS, JS+JJ ), 1 )
! 922: CALL DCOPY( MB, RHS( II ), 1, F( IS, JS+JJ ), 1 )
! 923: K = K + MB
! 924: II = II + MB
! 925: 180 CONTINUE
! 926: *
! 927: * Substitute R(I, J) and L(I, J) into remaining
! 928: * equation.
! 929: *
! 930: IF( J.GT.P+2 ) THEN
! 931: CALL DGEMM( 'N', 'T', MB, JS-1, NB, ONE,
! 932: $ C( IS, JS ), LDC, B( 1, JS ), LDB, ONE,
! 933: $ F( IS, 1 ), LDF )
! 934: CALL DGEMM( 'N', 'T', MB, JS-1, NB, ONE,
! 935: $ F( IS, JS ), LDF, E( 1, JS ), LDE, ONE,
! 936: $ F( IS, 1 ), LDF )
! 937: END IF
! 938: IF( I.LT.P ) THEN
! 939: CALL DGEMM( 'T', 'N', M-IE, NB, MB, -ONE,
! 940: $ A( IS, IE+1 ), LDA, C( IS, JS ), LDC,
! 941: $ ONE, C( IE+1, JS ), LDC )
! 942: CALL DGEMM( 'T', 'N', M-IE, NB, MB, -ONE,
! 943: $ D( IS, IE+1 ), LDD, F( IS, JS ), LDF,
! 944: $ ONE, C( IE+1, JS ), LDC )
! 945: END IF
! 946: *
! 947: END IF
! 948: *
! 949: 190 CONTINUE
! 950: 200 CONTINUE
! 951: *
! 952: END IF
! 953: RETURN
! 954: *
! 955: * End of DTGSY2
! 956: *
! 957: END
CVSweb interface <joel.bertrand@systella.fr>