Annotation of rpl/lapack/lapack/ztrsyl3.f, revision 1.1

1.1     ! bertrand    1: *> \brief \b ZTRSYL3
        !             2: *
        !             3: * Definition:
        !             4: * ===========
        !             5: *
        !             6: *
        !             7: *>  \par Purpose
        !             8: *  =============
        !             9: *>
        !            10: *> \verbatim
        !            11: *>
        !            12: *>  ZTRSYL3 solves the complex Sylvester matrix equation:
        !            13: *>
        !            14: *>     op(A)*X + X*op(B) = scale*C or
        !            15: *>     op(A)*X - X*op(B) = scale*C,
        !            16: *>
        !            17: *>  where op(A) = A or A**H, and  A and B are both upper triangular. A is
        !            18: *>  M-by-M and B is N-by-N; the right hand side C and the solution X are
        !            19: *>  M-by-N; and scale is an output scale factor, set <= 1 to avoid
        !            20: *>  overflow in X.
        !            21: *>
        !            22: *>  This is the block version of the algorithm.
        !            23: *> \endverbatim
        !            24: *
        !            25: *  Arguments
        !            26: *  =========
        !            27: *
        !            28: *> \param[in] TRANA
        !            29: *> \verbatim
        !            30: *>          TRANA is CHARACTER*1
        !            31: *>          Specifies the option op(A):
        !            32: *>          = 'N': op(A) = A    (No transpose)
        !            33: *>          = 'C': op(A) = A**H (Conjugate transpose)
        !            34: *> \endverbatim
        !            35: *>
        !            36: *> \param[in] TRANB
        !            37: *> \verbatim
        !            38: *>          TRANB is CHARACTER*1
        !            39: *>          Specifies the option op(B):
        !            40: *>          = 'N': op(B) = B    (No transpose)
        !            41: *>          = 'C': op(B) = B**H (Conjugate transpose)
        !            42: *> \endverbatim
        !            43: *>
        !            44: *> \param[in] ISGN
        !            45: *> \verbatim
        !            46: *>          ISGN is INTEGER
        !            47: *>          Specifies the sign in the equation:
        !            48: *>          = +1: solve op(A)*X + X*op(B) = scale*C
        !            49: *>          = -1: solve op(A)*X - X*op(B) = scale*C
        !            50: *> \endverbatim
        !            51: *>
        !            52: *> \param[in] M
        !            53: *> \verbatim
        !            54: *>          M is INTEGER
        !            55: *>          The order of the matrix A, and the number of rows in the
        !            56: *>          matrices X and C. M >= 0.
        !            57: *> \endverbatim
        !            58: *>
        !            59: *> \param[in] N
        !            60: *> \verbatim
        !            61: *>          N is INTEGER
        !            62: *>          The order of the matrix B, and the number of columns in the
        !            63: *>          matrices X and C. N >= 0.
        !            64: *> \endverbatim
        !            65: *>
        !            66: *> \param[in] A
        !            67: *> \verbatim
        !            68: *>          A is COMPLEX*16 array, dimension (LDA,M)
        !            69: *>          The upper triangular matrix A.
        !            70: *> \endverbatim
        !            71: *>
        !            72: *> \param[in] LDA
        !            73: *> \verbatim
        !            74: *>          LDA is INTEGER
        !            75: *>          The leading dimension of the array A. LDA >= max(1,M).
        !            76: *> \endverbatim
        !            77: *>
        !            78: *> \param[in] B
        !            79: *> \verbatim
        !            80: *>          B is COMPLEX*16 array, dimension (LDB,N)
        !            81: *>          The upper triangular matrix B.
        !            82: *> \endverbatim
        !            83: *>
        !            84: *> \param[in] LDB
        !            85: *> \verbatim
        !            86: *>          LDB is INTEGER
        !            87: *>          The leading dimension of the array B. LDB >= max(1,N).
        !            88: *> \endverbatim
        !            89: *>
        !            90: *> \param[in,out] C
        !            91: *> \verbatim
        !            92: *>          C is COMPLEX*16 array, dimension (LDC,N)
        !            93: *>          On entry, the M-by-N right hand side matrix C.
        !            94: *>          On exit, C is overwritten by the solution matrix X.
        !            95: *> \endverbatim
        !            96: *>
        !            97: *> \param[in] LDC
        !            98: *> \verbatim
        !            99: *>          LDC is INTEGER
        !           100: *>          The leading dimension of the array C. LDC >= max(1,M)
        !           101: *> \endverbatim
        !           102: *>
        !           103: *> \param[out] SCALE
        !           104: *> \verbatim
        !           105: *>          SCALE is DOUBLE PRECISION
        !           106: *>          The scale factor, scale, set <= 1 to avoid overflow in X.
        !           107: *> \endverbatim
        !           108: *>
        !           109: *> \param[out] SWORK
        !           110: *> \verbatim
        !           111: *>          SWORK is DOUBLE PRECISION array, dimension (MAX(2, ROWS),
        !           112: *>          MAX(1,COLS)).
        !           113: *>          On exit, if INFO = 0, SWORK(1) returns the optimal value ROWS
        !           114: *>          and SWORK(2) returns the optimal COLS.
        !           115: *> \endverbatim
        !           116: *>
        !           117: *> \param[in] LDSWORK
        !           118: *> \verbatim
        !           119: *>          LDSWORK is INTEGER
        !           120: *>          LDSWORK >= MAX(2,ROWS), where ROWS = ((M + NB - 1) / NB + 1)
        !           121: *>          and NB is the optimal block size.
        !           122: *>
        !           123: *>          If LDSWORK = -1, then a workspace query is assumed; the routine
        !           124: *>          only calculates the optimal dimensions of the SWORK matrix,
        !           125: *>          returns these values as the first and second entry of the SWORK
        !           126: *>          matrix, and no error message related LWORK is issued by XERBLA.
        !           127: *> \endverbatim
        !           128: *>
        !           129: *> \param[out] INFO
        !           130: *> \verbatim
        !           131: *>          INFO is INTEGER
        !           132: *>          = 0: successful exit
        !           133: *>          < 0: if INFO = -i, the i-th argument had an illegal value
        !           134: *>          = 1: A and B have common or very close eigenvalues; perturbed
        !           135: *>               values were used to solve the equation (but the matrices
        !           136: *>               A and B are unchanged).
        !           137: *> \endverbatim
        !           138: *
        !           139: *> \ingroup complex16SYcomputational
        !           140: *
        !           141: *  =====================================================================
        !           142: *  References:
        !           143: *   E. S. Quintana-Orti and R. A. Van De Geijn (2003). Formal derivation of
        !           144: *   algorithms: The triangular Sylvester equation, ACM Transactions
        !           145: *   on Mathematical Software (TOMS), volume 29, pages 218--243.
        !           146: *
        !           147: *   A. Schwarz and C. C. Kjelgaard Mikkelsen (2020). Robust Task-Parallel
        !           148: *   Solution of the Triangular Sylvester Equation. Lecture Notes in
        !           149: *   Computer Science, vol 12043, pages 82--92, Springer.
        !           150: *
        !           151: *  Contributor:
        !           152: *   Angelika Schwarz, Umea University, Sweden.
        !           153: *
        !           154: *  =====================================================================
        !           155:       SUBROUTINE ZTRSYL3( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,
        !           156:      $                    LDC, SCALE, SWORK, LDSWORK, INFO )
        !           157:       IMPLICIT NONE
        !           158: *
        !           159: *     .. Scalar Arguments ..
        !           160:       CHARACTER          TRANA, TRANB
        !           161:       INTEGER            INFO, ISGN, LDA, LDB, LDC, LDSWORK, M, N
        !           162:       DOUBLE PRECISION   SCALE
        !           163: *     ..
        !           164: *     .. Array Arguments ..
        !           165:       COMPLEX*16         A( LDA, * ), B( LDB, * ), C( LDC, * )
        !           166:       DOUBLE PRECISION   SWORK( LDSWORK, * )
        !           167: *     ..
        !           168: *     .. Parameters ..
        !           169:       DOUBLE PRECISION   ZERO, ONE
        !           170:       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
        !           171:       COMPLEX*16         CONE
        !           172:       PARAMETER          ( CONE = ( 1.0D0, 0.0D0 ) )
        !           173: *     ..
        !           174: *     .. Local Scalars ..
        !           175:       LOGICAL            NOTRNA, NOTRNB, LQUERY
        !           176:       INTEGER            AWRK, BWRK, I, I1, I2, IINFO, J, J1, J2, JJ,
        !           177:      $                   K, K1, K2, L, L1, L2, LL, NBA, NB, NBB
        !           178:       DOUBLE PRECISION   ANRM, BIGNUM, BNRM, CNRM, SCAL, SCALOC,
        !           179:      $                   SCAMIN, SGN, XNRM, BUF, SMLNUM
        !           180:       COMPLEX*16         CSGN
        !           181: *     ..
        !           182: *     .. Local Arrays ..
        !           183:       DOUBLE PRECISION   WNRM( MAX( M, N ) )
        !           184: *     ..
        !           185: *     .. External Functions ..
        !           186:       LOGICAL            LSAME
        !           187:       INTEGER            ILAENV
        !           188:       DOUBLE PRECISION   DLAMCH, DLARMM, ZLANGE
        !           189:       EXTERNAL           DLAMCH, DLARMM, ILAENV, LSAME, ZLANGE
        !           190: *     ..
        !           191: *     .. External Subroutines ..
        !           192:       EXTERNAL           XERBLA, ZDSCAL, ZGEMM, ZLASCL, ZTRSYL
        !           193: *     ..
        !           194: *     .. Intrinsic Functions ..
        !           195:       INTRINSIC          ABS, DBLE, DIMAG, EXPONENT, MAX, MIN
        !           196: *     ..
        !           197: *     .. Executable Statements ..
        !           198: *
        !           199: *     Decode and Test input parameters
        !           200: *
        !           201:       NOTRNA = LSAME( TRANA, 'N' )
        !           202:       NOTRNB = LSAME( TRANB, 'N' )
        !           203: *
        !           204: *     Use the same block size for all matrices.
        !           205: *
        !           206:       NB = MAX( 8, ILAENV( 1, 'ZTRSYL', '', M, N, -1, -1) )
        !           207: *
        !           208: *     Compute number of blocks in A and B
        !           209: *
        !           210:       NBA = MAX( 1, (M + NB - 1) / NB )
        !           211:       NBB = MAX( 1, (N + NB - 1) / NB )
        !           212: *
        !           213: *     Compute workspace
        !           214: *
        !           215:       INFO = 0
        !           216:       LQUERY = ( LDSWORK.EQ.-1 )
        !           217:       IF( LQUERY ) THEN
        !           218:          LDSWORK = 2
        !           219:          SWORK(1,1) = MAX( NBA, NBB )
        !           220:          SWORK(2,1) = 2 * NBB + NBA
        !           221:       END IF
        !           222: *
        !           223: *     Test the input arguments
        !           224: *
        !           225:       IF( .NOT.NOTRNA .AND. .NOT. LSAME( TRANA, 'C' ) ) THEN
        !           226:          INFO = -1
        !           227:       ELSE IF( .NOT.NOTRNB .AND. .NOT. LSAME( TRANB, 'C' ) ) THEN
        !           228:          INFO = -2
        !           229:       ELSE IF( ISGN.NE.1 .AND. ISGN.NE.-1 ) THEN
        !           230:          INFO = -3
        !           231:       ELSE IF( M.LT.0 ) THEN
        !           232:          INFO = -4
        !           233:       ELSE IF( N.LT.0 ) THEN
        !           234:          INFO = -5
        !           235:       ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
        !           236:          INFO = -7
        !           237:       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
        !           238:          INFO = -9
        !           239:       ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
        !           240:          INFO = -11
        !           241:       END IF
        !           242:       IF( INFO.NE.0 ) THEN
        !           243:          CALL XERBLA( 'ZTRSYL3', -INFO )
        !           244:          RETURN
        !           245:       ELSE IF( LQUERY ) THEN
        !           246:          RETURN
        !           247:       END IF
        !           248: *
        !           249: *     Quick return if possible
        !           250: *
        !           251:       SCALE = ONE
        !           252:       IF( M.EQ.0 .OR. N.EQ.0 )
        !           253:      $   RETURN
        !           254: *
        !           255: *     Use unblocked code for small problems or if insufficient
        !           256: *     workspace is provided
        !           257: *
        !           258:       IF( MIN( NBA, NBB ).EQ.1 .OR. LDSWORK.LT.MAX( NBA, NBB ) ) THEN
        !           259:         CALL ZTRSYL( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB,
        !           260:      $               C, LDC, SCALE, INFO )
        !           261:         RETURN
        !           262:       END IF
        !           263: *
        !           264: *     Set constants to control overflow
        !           265: *
        !           266:       SMLNUM = DLAMCH( 'S' )
        !           267:       BIGNUM = ONE / SMLNUM
        !           268: *
        !           269: *     Set local scaling factors.
        !           270: *
        !           271:       DO L = 1, NBB
        !           272:          DO K = 1, NBA
        !           273:             SWORK( K, L ) = ONE
        !           274:          END DO
        !           275:       END DO
        !           276: *
        !           277: *     Fallback scaling factor to prevent flushing of SWORK( K, L ) to zero.
        !           278: *     This scaling is to ensure compatibility with TRSYL and may get flushed.
        !           279: *
        !           280:       BUF = ONE
        !           281: *
        !           282: *      Compute upper bounds of blocks of A and B
        !           283: *
        !           284:       AWRK = NBB
        !           285:       DO K = 1, NBA
        !           286:          K1 = (K - 1) * NB + 1
        !           287:          K2 = MIN( K * NB, M ) + 1
        !           288:          DO L = K, NBA
        !           289:             L1 = (L - 1) * NB + 1
        !           290:             L2 = MIN( L * NB, M ) + 1
        !           291:             IF( NOTRNA ) THEN
        !           292:                SWORK( K, AWRK + L ) = ZLANGE( 'I', K2-K1, L2-L1,
        !           293:      $                                        A( K1, L1 ), LDA, WNRM )
        !           294:             ELSE
        !           295:                SWORK( L, AWRK + K ) = ZLANGE( '1', K2-K1, L2-L1,
        !           296:      $                                        A( K1, L1 ), LDA, WNRM )
        !           297:             END IF
        !           298:          END DO
        !           299:       END DO
        !           300:       BWRK = NBB + NBA
        !           301:       DO K = 1, NBB
        !           302:          K1 = (K - 1) * NB + 1
        !           303:          K2 = MIN( K * NB, N ) + 1
        !           304:          DO L = K, NBB
        !           305:             L1 = (L - 1) * NB + 1
        !           306:             L2 = MIN( L * NB, N ) + 1
        !           307:             IF( NOTRNB ) THEN
        !           308:                SWORK( K, BWRK + L ) = ZLANGE( 'I', K2-K1, L2-L1,
        !           309:      $                                        B( K1, L1 ), LDB, WNRM )
        !           310:             ELSE
        !           311:                SWORK( L, BWRK + K ) = ZLANGE( '1', K2-K1, L2-L1,
        !           312:      $                                        B( K1, L1 ), LDB, WNRM )
        !           313:             END IF
        !           314:          END DO
        !           315:       END DO
        !           316: *
        !           317:       SGN = DBLE( ISGN )
        !           318:       CSGN = DCMPLX( SGN, ZERO )
        !           319: *
        !           320:       IF( NOTRNA .AND. NOTRNB ) THEN
        !           321: *
        !           322: *        Solve    A*X + ISGN*X*B = scale*C.
        !           323: *
        !           324: *        The (K,L)th block of X is determined starting from
        !           325: *        bottom-left corner column by column by
        !           326: *
        !           327: *         A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
        !           328: *
        !           329: *        Where
        !           330: *                  M                         L-1
        !           331: *        R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B(J,L)].
        !           332: *                I=K+1                       J=1
        !           333: *
        !           334: *        Start loop over block rows (index = K) and block columns (index = L)
        !           335: *
        !           336:          DO K = NBA, 1, -1
        !           337: *
        !           338: *           K1: row index of the first row in X( K, L )
        !           339: *           K2: row index of the first row in X( K+1, L )
        !           340: *           so the K2 - K1 is the column count of the block X( K, L )
        !           341: *
        !           342:             K1 = (K - 1) * NB + 1
        !           343:             K2 = MIN( K * NB, M ) + 1
        !           344:             DO L = 1, NBB
        !           345: *
        !           346: *              L1: column index of the first column in X( K, L )
        !           347: *              L2: column index of the first column in X( K, L + 1)
        !           348: *              so that L2 - L1 is the row count of the block X( K, L )
        !           349: *
        !           350:                L1 = (L - 1) * NB + 1
        !           351:                L2 = MIN( L * NB, N ) + 1
        !           352: *
        !           353:                CALL ZTRSYL( TRANA, TRANB, ISGN, K2-K1, L2-L1,
        !           354:      $                      A( K1, K1 ), LDA,
        !           355:      $                      B( L1, L1 ), LDB,
        !           356:      $                      C( K1, L1 ), LDC, SCALOC, IINFO )
        !           357:                INFO = MAX( INFO, IINFO )
        !           358: *
        !           359:                IF( SCALOC * SWORK( K, L ) .EQ. ZERO ) THEN
        !           360:                   IF( SCALOC .EQ. ZERO ) THEN
        !           361: *                    The magnitude of the largest entry of X(K1:K2-1, L1:L2-1)
        !           362: *                    is larger than the product of BIGNUM**2 and cannot be
        !           363: *                    represented in the form (1/SCALE)*X(K1:K2-1, L1:L2-1).
        !           364: *                    Mark the computation as pointless.
        !           365:                      BUF = ZERO
        !           366:                   ELSE
        !           367:                      BUF = BUF*2.D0**EXPONENT( SCALOC )
        !           368:                   END IF
        !           369:                   DO JJ = 1, NBB
        !           370:                      DO LL = 1, NBA
        !           371: *                       Bound by BIGNUM to not introduce Inf. The value
        !           372: *                       is irrelevant; corresponding entries of the
        !           373: *                       solution will be flushed in consistency scaling.
        !           374:                         SWORK( LL, JJ ) = MIN( BIGNUM,
        !           375:      $                     SWORK( LL, JJ ) / 2.D0**EXPONENT( SCALOC ) )
        !           376:                      END DO
        !           377:                   END DO
        !           378:                END IF
        !           379:                SWORK( K, L ) = SCALOC * SWORK( K, L )
        !           380:                XNRM = ZLANGE( 'I', K2-K1, L2-L1, C( K1, L1 ), LDC,
        !           381:      $                        WNRM )
        !           382: *
        !           383:                DO I = K - 1, 1, -1
        !           384: *
        !           385: *                 C( I, L ) := C( I, L ) - A( I, K ) * C( K, L )
        !           386: *
        !           387:                   I1 = (I - 1) * NB + 1
        !           388:                   I2 = MIN( I * NB, M ) + 1
        !           389: *
        !           390: *                 Compute scaling factor to survive the linear update
        !           391: *                 simulating consistent scaling.
        !           392: *
        !           393:                   CNRM = ZLANGE( 'I', I2-I1, L2-L1, C( I1, L1 ),
        !           394:      $                           LDC, WNRM )
        !           395:                   SCAMIN = MIN( SWORK( I, L ), SWORK( K, L ) )
        !           396:                   CNRM = CNRM * ( SCAMIN / SWORK( I, L ) )
        !           397:                   XNRM = XNRM * ( SCAMIN / SWORK( K, L ) )
        !           398:                   ANRM = SWORK( I, AWRK + K )
        !           399:                   SCALOC = DLARMM( ANRM, XNRM, CNRM )
        !           400:                   IF( SCALOC * SCAMIN .EQ. ZERO ) THEN
        !           401: *                    Use second scaling factor to prevent flushing to zero.
        !           402:                      BUF = BUF*2.D0**EXPONENT( SCALOC )
        !           403:                      DO JJ = 1, NBB
        !           404:                         DO LL = 1, NBA
        !           405:                         SWORK( LL, JJ ) = MIN( BIGNUM,
        !           406:      $                     SWORK( LL, JJ ) / 2.D0**EXPONENT( SCALOC ) )
        !           407:                         END DO
        !           408:                      END DO
        !           409:                      SCAMIN = SCAMIN / 2.D0**EXPONENT( SCALOC )
        !           410:                      SCALOC = SCALOC / 2.D0**EXPONENT( SCALOC )
        !           411:                   END IF
        !           412:                   CNRM = CNRM * SCALOC
        !           413:                   XNRM = XNRM * SCALOC
        !           414: *
        !           415: *                 Simultaneously apply the robust update factor and the
        !           416: *                 consistency scaling factor to C( I, L ) and C( K, L ).
        !           417: *
        !           418:                   SCAL = ( SCAMIN / SWORK( K, L ) ) * SCALOC
        !           419:                   IF( SCAL .NE. ONE ) THEN
        !           420:                       DO JJ = L1, L2-1
        !           421:                          CALL ZDSCAL( K2-K1, SCAL, C( K1, JJ ), 1)
        !           422:                       END DO
        !           423:                   ENDIF
        !           424: *
        !           425:                   SCAL = ( SCAMIN / SWORK( I, L ) ) * SCALOC
        !           426:                   IF( SCAL .NE. ONE ) THEN
        !           427:                       DO LL = L1, L2-1
        !           428:                          CALL ZDSCAL( I2-I1, SCAL, C( I1, LL ), 1)
        !           429:                       END DO
        !           430:                   ENDIF
        !           431: *
        !           432: *                 Record current scaling factor
        !           433: *
        !           434:                   SWORK( K, L ) = SCAMIN * SCALOC
        !           435:                   SWORK( I, L ) = SCAMIN * SCALOC
        !           436: *
        !           437:                   CALL ZGEMM( 'N', 'N', I2-I1, L2-L1, K2-K1, -CONE,
        !           438:      $                        A( I1, K1 ), LDA, C( K1, L1 ), LDC,
        !           439:      $                        CONE, C( I1, L1 ), LDC )
        !           440: *
        !           441:                END DO
        !           442: *
        !           443:                DO J = L + 1, NBB
        !           444: *
        !           445: *                 C( K, J ) := C( K, J ) - SGN * C( K, L ) * B( L, J )
        !           446: *
        !           447:                   J1 = (J - 1) * NB + 1
        !           448:                   J2 = MIN( J * NB, N ) + 1
        !           449: *
        !           450: *                 Compute scaling factor to survive the linear update
        !           451: *                 simulating consistent scaling.
        !           452: *
        !           453:                   CNRM = ZLANGE( 'I', K2-K1, J2-J1, C( K1, J1 ),
        !           454:      $                           LDC, WNRM )
        !           455:                   SCAMIN = MIN( SWORK( K, J ), SWORK( K, L ) )
        !           456:                   CNRM = CNRM * ( SCAMIN / SWORK( K, J ) )
        !           457:                   XNRM = XNRM * ( SCAMIN / SWORK( K, L ) )
        !           458:                   BNRM = SWORK(L, BWRK + J)
        !           459:                   SCALOC = DLARMM( BNRM, XNRM, CNRM )
        !           460:                   IF( SCALOC * SCAMIN .EQ. ZERO ) THEN
        !           461: *                    Use second scaling factor to prevent flushing to zero.
        !           462:                      BUF = BUF*2.D0**EXPONENT( SCALOC )
        !           463:                      DO JJ = 1, NBB
        !           464:                         DO LL = 1, NBA
        !           465:                         SWORK( LL, JJ ) = MIN( BIGNUM,
        !           466:      $                     SWORK( LL, JJ ) / 2.D0**EXPONENT( SCALOC ) )
        !           467:                         END DO
        !           468:                      END DO
        !           469:                      SCAMIN = SCAMIN / 2.D0**EXPONENT( SCALOC )
        !           470:                      SCALOC = SCALOC / 2.D0**EXPONENT( SCALOC )
        !           471:                   END IF
        !           472:                   CNRM = CNRM * SCALOC
        !           473:                   XNRM = XNRM * SCALOC
        !           474: *
        !           475: *                 Simultaneously apply the robust update factor and the
        !           476: *                 consistency scaling factor to C( K, J ) and C( K, L).
        !           477: *
        !           478:                   SCAL = ( SCAMIN / SWORK( K, L ) ) * SCALOC
        !           479:                   IF( SCAL .NE. ONE ) THEN
        !           480:                      DO LL = L1, L2-1
        !           481:                         CALL ZDSCAL( K2-K1, SCAL, C( K1, LL ), 1 )
        !           482:                      END DO
        !           483:                   ENDIF
        !           484: *
        !           485:                   SCAL = ( SCAMIN / SWORK( K, J ) ) * SCALOC
        !           486:                   IF( SCAL .NE. ONE ) THEN
        !           487:                       DO JJ = J1, J2-1
        !           488:                          CALL ZDSCAL( K2-K1, SCAL, C( K1, JJ ), 1 )
        !           489:                       END DO
        !           490:                   ENDIF
        !           491: *
        !           492: *                 Record current scaling factor
        !           493: *
        !           494:                   SWORK( K, L ) = SCAMIN * SCALOC
        !           495:                   SWORK( K, J ) = SCAMIN * SCALOC
        !           496: *
        !           497:                   CALL ZGEMM( 'N', 'N', K2-K1, J2-J1, L2-L1, -CSGN,
        !           498:      $                        C( K1, L1 ), LDC, B( L1, J1 ), LDB,
        !           499:      $                        CONE, C( K1, J1 ), LDC )
        !           500:                END DO
        !           501:             END DO
        !           502:          END DO
        !           503:       ELSE IF( .NOT.NOTRNA .AND. NOTRNB ) THEN
        !           504: *
        !           505: *        Solve    A**H *X + ISGN*X*B = scale*C.
        !           506: *
        !           507: *        The (K,L)th block of X is determined starting from
        !           508: *        upper-left corner column by column by
        !           509: *
        !           510: *          A(K,K)**H*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)
        !           511: *
        !           512: *        Where
        !           513: *                   K-1                        L-1
        !           514: *          R(K,L) = SUM [A(I,K)**H*X(I,L)] +ISGN*SUM [X(K,J)*B(J,L)]
        !           515: *                   I=1                        J=1
        !           516: *
        !           517: *        Start loop over block rows (index = K) and block columns (index = L)
        !           518: *
        !           519:          DO K = 1, NBA
        !           520: *
        !           521: *           K1: row index of the first row in X( K, L )
        !           522: *           K2: row index of the first row in X( K+1, L )
        !           523: *           so the K2 - K1 is the column count of the block X( K, L )
        !           524: *
        !           525:             K1 = (K - 1) * NB + 1
        !           526:             K2 = MIN( K * NB, M ) + 1
        !           527:             DO L = 1, NBB
        !           528: *
        !           529: *              L1: column index of the first column in X( K, L )
        !           530: *              L2: column index of the first column in X( K, L + 1)
        !           531: *              so that L2 - L1 is the row count of the block X( K, L )
        !           532: *
        !           533:                L1 = (L - 1) * NB + 1
        !           534:                L2 = MIN( L * NB, N ) + 1
        !           535: *
        !           536:                CALL ZTRSYL( TRANA, TRANB, ISGN, K2-K1, L2-L1,
        !           537:      $                      A( K1, K1 ), LDA,
        !           538:      $                      B( L1, L1 ), LDB,
        !           539:      $                      C( K1, L1 ), LDC, SCALOC, IINFO )
        !           540:                INFO = MAX( INFO, IINFO )
        !           541: *
        !           542:                IF( SCALOC * SWORK( K, L ) .EQ. ZERO ) THEN
        !           543:                   IF( SCALOC .EQ. ZERO ) THEN
        !           544: *                    The magnitude of the largest entry of X(K1:K2-1, L1:L2-1)
        !           545: *                    is larger than the product of BIGNUM**2 and cannot be
        !           546: *                    represented in the form (1/SCALE)*X(K1:K2-1, L1:L2-1).
        !           547: *                    Mark the computation as pointless.
        !           548:                      BUF = ZERO
        !           549:                   ELSE
        !           550: *                    Use second scaling factor to prevent flushing to zero.
        !           551:                      BUF = BUF*2.D0**EXPONENT( SCALOC )
        !           552:                   END IF
        !           553:                   DO JJ = 1, NBB
        !           554:                      DO LL = 1, NBA
        !           555: *                       Bound by BIGNUM to not introduce Inf. The value
        !           556: *                       is irrelevant; corresponding entries of the
        !           557: *                       solution will be flushed in consistency scaling.
        !           558:                         SWORK( LL, JJ ) = MIN( BIGNUM,
        !           559:      $                     SWORK( LL, JJ ) / 2.D0**EXPONENT( SCALOC ) )
        !           560:                      END DO
        !           561:                   END DO
        !           562:                END IF
        !           563:                SWORK( K, L ) = SCALOC * SWORK( K, L )
        !           564:                XNRM = ZLANGE( 'I', K2-K1, L2-L1, C( K1, L1 ), LDC,
        !           565:      $                        WNRM )
        !           566: *
        !           567:                DO I = K + 1, NBA
        !           568: *
        !           569: *                 C( I, L ) := C( I, L ) - A( K, I )**H * C( K, L )
        !           570: *
        !           571:                   I1 = (I - 1) * NB + 1
        !           572:                   I2 = MIN( I * NB, M ) + 1
        !           573: *
        !           574: *                 Compute scaling factor to survive the linear update
        !           575: *                 simulating consistent scaling.
        !           576: *
        !           577:                   CNRM = ZLANGE( 'I', I2-I1, L2-L1, C( I1, L1 ),
        !           578:      $                           LDC, WNRM )
        !           579:                   SCAMIN = MIN( SWORK( I, L ), SWORK( K, L ) )
        !           580:                   CNRM = CNRM * ( SCAMIN / SWORK( I, L ) )
        !           581:                   XNRM = XNRM * ( SCAMIN / SWORK( K, L ) )
        !           582:                   ANRM = SWORK( I, AWRK + K )
        !           583:                   SCALOC = DLARMM( ANRM, XNRM, CNRM )
        !           584:                   IF( SCALOC * SCAMIN .EQ. ZERO ) THEN
        !           585: *                    Use second scaling factor to prevent flushing to zero.
        !           586:                      BUF = BUF*2.D0**EXPONENT( SCALOC )
        !           587:                      DO JJ = 1, NBB
        !           588:                         DO LL = 1, NBA
        !           589:                         SWORK( LL, JJ ) = MIN( BIGNUM,
        !           590:      $                     SWORK( LL, JJ ) / 2.D0**EXPONENT( SCALOC ) )
        !           591:                         END DO
        !           592:                      END DO
        !           593:                      SCAMIN = SCAMIN / 2.D0**EXPONENT( SCALOC )
        !           594:                      SCALOC = SCALOC / 2.D0**EXPONENT( SCALOC )
        !           595:                   END IF
        !           596:                   CNRM = CNRM * SCALOC
        !           597:                   XNRM = XNRM * SCALOC
        !           598: *
        !           599: *                 Simultaneously apply the robust update factor and the
        !           600: *                 consistency scaling factor to to C( I, L ) and C( K, L).
        !           601: *
        !           602:                   SCAL = ( SCAMIN / SWORK( K, L ) ) * SCALOC
        !           603:                   IF( SCAL .NE. ONE ) THEN
        !           604:                      DO LL = L1, L2-1
        !           605:                         CALL ZDSCAL( K2-K1, SCAL, C( K1, LL ), 1 )
        !           606:                      END DO
        !           607:                   ENDIF
        !           608: *
        !           609:                   SCAL = ( SCAMIN / SWORK( I, L ) ) * SCALOC
        !           610:                   IF( SCAL .NE. ONE ) THEN
        !           611:                      DO LL = L1, L2-1
        !           612:                         CALL ZDSCAL( I2-I1, SCAL, C( I1, LL ), 1 )
        !           613:                      END DO
        !           614:                   ENDIF
        !           615: *
        !           616: *                 Record current scaling factor
        !           617: *
        !           618:                   SWORK( K, L ) = SCAMIN * SCALOC
        !           619:                   SWORK( I, L ) = SCAMIN * SCALOC
        !           620: *
        !           621:                   CALL ZGEMM( 'C', 'N', I2-I1, L2-L1, K2-K1, -CONE,
        !           622:      $                        A( K1, I1 ), LDA, C( K1, L1 ), LDC,
        !           623:      $                        CONE, C( I1, L1 ), LDC )
        !           624:                END DO
        !           625: *
        !           626:                DO J = L + 1, NBB
        !           627: *
        !           628: *                 C( K, J ) := C( K, J ) - SGN * C( K, L ) * B( L, J )
        !           629: *
        !           630:                   J1 = (J - 1) * NB + 1
        !           631:                   J2 = MIN( J * NB, N ) + 1
        !           632: *
        !           633: *                 Compute scaling factor to survive the linear update
        !           634: *                 simulating consistent scaling.
        !           635: *
        !           636:                   CNRM = ZLANGE( 'I', K2-K1, J2-J1, C( K1, J1 ),
        !           637:      $                           LDC, WNRM )
        !           638:                   SCAMIN = MIN( SWORK( K, J ), SWORK( K, L ) )
        !           639:                   CNRM = CNRM * ( SCAMIN / SWORK( K, J ) )
        !           640:                   XNRM = XNRM * ( SCAMIN / SWORK( K, L ) )
        !           641:                   BNRM = SWORK( L, BWRK + J )
        !           642:                   SCALOC = DLARMM( BNRM, XNRM, CNRM )
        !           643:                   IF( SCALOC * SCAMIN .EQ. ZERO ) THEN
        !           644: *                    Use second scaling factor to prevent flushing to zero.
        !           645:                      BUF = BUF*2.D0**EXPONENT( SCALOC )
        !           646:                      DO JJ = 1, NBB
        !           647:                         DO LL = 1, NBA
        !           648:                         SWORK( LL, JJ ) = MIN( BIGNUM,
        !           649:      $                     SWORK( LL, JJ ) / 2.D0**EXPONENT( SCALOC ) )
        !           650:                         END DO
        !           651:                      END DO
        !           652:                      SCAMIN = SCAMIN / 2.D0**EXPONENT( SCALOC )
        !           653:                      SCALOC = SCALOC / 2.D0**EXPONENT( SCALOC )
        !           654:                   END IF
        !           655:                   CNRM = CNRM * SCALOC
        !           656:                   XNRM = XNRM * SCALOC
        !           657: *
        !           658: *                 Simultaneously apply the robust update factor and the
        !           659: *                 consistency scaling factor to to C( K, J ) and C( K, L).
        !           660: *
        !           661:                   SCAL = ( SCAMIN / SWORK( K, L ) ) * SCALOC
        !           662:                   IF( SCAL .NE. ONE ) THEN
        !           663:                       DO LL = L1, L2-1
        !           664:                          CALL ZDSCAL( K2-K1, SCAL, C( K1, LL ), 1 )
        !           665:                       END DO
        !           666:                   ENDIF
        !           667: *
        !           668:                   SCAL = ( SCAMIN / SWORK( K, J ) ) * SCALOC
        !           669:                   IF( SCAL .NE. ONE ) THEN
        !           670:                      DO JJ = J1, J2-1
        !           671:                         CALL ZDSCAL( K2-K1, SCAL, C( K1, JJ ), 1 )
        !           672:                      END DO
        !           673:                   ENDIF
        !           674: *
        !           675: *                 Record current scaling factor
        !           676: *
        !           677:                   SWORK( K, L ) = SCAMIN * SCALOC
        !           678:                   SWORK( K, J ) = SCAMIN * SCALOC
        !           679: *
        !           680:                   CALL ZGEMM( 'N', 'N', K2-K1, J2-J1, L2-L1, -CSGN,
        !           681:      $                        C( K1, L1 ), LDC, B( L1, J1 ), LDB,
        !           682:      $                        CONE, C( K1, J1 ), LDC )
        !           683:                END DO
        !           684:             END DO
        !           685:          END DO
        !           686:       ELSE IF( .NOT.NOTRNA .AND. .NOT.NOTRNB ) THEN
        !           687: *
        !           688: *        Solve    A**H *X + ISGN*X*B**H = scale*C.
        !           689: *
        !           690: *        The (K,L)th block of X is determined starting from
        !           691: *        top-right corner column by column by
        !           692: *
        !           693: *           A(K,K)**H*X(K,L) + ISGN*X(K,L)*B(L,L)**H = C(K,L) - R(K,L)
        !           694: *
        !           695: *        Where
        !           696: *                     K-1                          N
        !           697: *            R(K,L) = SUM [A(I,K)**H*X(I,L)] + ISGN*SUM [X(K,J)*B(L,J)**H].
        !           698: *                     I=1                        J=L+1
        !           699: *
        !           700: *        Start loop over block rows (index = K) and block columns (index = L)
        !           701: *
        !           702:          DO K = 1, NBA
        !           703: *
        !           704: *           K1: row index of the first row in X( K, L )
        !           705: *           K2: row index of the first row in X( K+1, L )
        !           706: *           so the K2 - K1 is the column count of the block X( K, L )
        !           707: *
        !           708:             K1 = (K - 1) * NB + 1
        !           709:             K2 = MIN( K * NB, M ) + 1
        !           710:             DO L = NBB, 1, -1
        !           711: *
        !           712: *              L1: column index of the first column in X( K, L )
        !           713: *              L2: column index of the first column in X( K, L + 1)
        !           714: *              so that L2 - L1 is the row count of the block X( K, L )
        !           715: *
        !           716:                L1 = (L - 1) * NB + 1
        !           717:                L2 = MIN( L * NB, N ) + 1
        !           718: *
        !           719:                CALL ZTRSYL( TRANA, TRANB, ISGN, K2-K1, L2-L1,
        !           720:      $                      A( K1, K1 ), LDA,
        !           721:      $                      B( L1, L1 ), LDB,
        !           722:      $                      C( K1, L1 ), LDC, SCALOC, IINFO )
        !           723:                INFO = MAX( INFO, IINFO )
        !           724: *
        !           725:                IF( SCALOC * SWORK( K, L ) .EQ. ZERO ) THEN
        !           726:                   IF( SCALOC .EQ. ZERO ) THEN
        !           727: *                    The magnitude of the largest entry of X(K1:K2-1, L1:L2-1)
        !           728: *                    is larger than the product of BIGNUM**2 and cannot be
        !           729: *                    represented in the form (1/SCALE)*X(K1:K2-1, L1:L2-1).
        !           730: *                    Mark the computation as pointless.
        !           731:                      BUF = ZERO
        !           732:                   ELSE
        !           733: *                    Use second scaling factor to prevent flushing to zero.
        !           734:                      BUF = BUF*2.D0**EXPONENT( SCALOC )
        !           735:                   END IF
        !           736:                   DO JJ = 1, NBB
        !           737:                      DO LL = 1, NBA
        !           738: *                       Bound by BIGNUM to not introduce Inf. The value
        !           739: *                       is irrelevant; corresponding entries of the
        !           740: *                       solution will be flushed in consistency scaling.
        !           741:                         SWORK( LL, JJ ) = MIN( BIGNUM,
        !           742:      $                     SWORK( LL, JJ ) / 2.D0**EXPONENT( SCALOC ) )
        !           743:                      END DO
        !           744:                   END DO
        !           745:                END IF
        !           746:                SWORK( K, L ) = SCALOC * SWORK( K, L )
        !           747:                XNRM = ZLANGE( 'I', K2-K1, L2-L1, C( K1, L1 ), LDC,
        !           748:      $                        WNRM )
        !           749: *
        !           750:                DO I = K + 1, NBA
        !           751: *
        !           752: *                 C( I, L ) := C( I, L ) - A( K, I )**H * C( K, L )
        !           753: *
        !           754:                   I1 = (I - 1) * NB + 1
        !           755:                   I2 = MIN( I * NB, M ) + 1
        !           756: *
        !           757: *                 Compute scaling factor to survive the linear update
        !           758: *                 simulating consistent scaling.
        !           759: *
        !           760:                   CNRM = ZLANGE( 'I', I2-I1, L2-L1, C( I1, L1 ),
        !           761:      $                           LDC, WNRM )
        !           762:                   SCAMIN = MIN( SWORK( I, L ), SWORK( K, L ) )
        !           763:                   CNRM = CNRM * ( SCAMIN / SWORK( I, L ) )
        !           764:                   XNRM = XNRM * ( SCAMIN / SWORK( K, L ) )
        !           765:                   ANRM = SWORK( I, AWRK + K )
        !           766:                   SCALOC = DLARMM( ANRM, XNRM, CNRM )
        !           767:                   IF( SCALOC * SCAMIN .EQ. ZERO ) THEN
        !           768: *                    Use second scaling factor to prevent flushing to zero.
        !           769:                      BUF = BUF*2.D0**EXPONENT( SCALOC )
        !           770:                      DO JJ = 1, NBB
        !           771:                         DO LL = 1, NBA
        !           772:                         SWORK( LL, JJ ) = MIN( BIGNUM,
        !           773:      $                     SWORK( LL, JJ ) / 2.D0**EXPONENT( SCALOC ) )
        !           774:                         END DO
        !           775:                      END DO
        !           776:                      SCAMIN = SCAMIN / 2.D0**EXPONENT( SCALOC )
        !           777:                      SCALOC = SCALOC / 2.D0**EXPONENT( SCALOC )
        !           778:                   END IF
        !           779:                   CNRM = CNRM * SCALOC
        !           780:                   XNRM = XNRM * SCALOC
        !           781: *
        !           782: *                 Simultaneously apply the robust update factor and the
        !           783: *                 consistency scaling factor to C( I, L ) and C( K, L).
        !           784: *
        !           785:                   SCAL = ( SCAMIN / SWORK( K, L ) ) * SCALOC
        !           786:                   IF( SCAL .NE. ONE ) THEN
        !           787:                      DO LL = L1, L2-1
        !           788:                         CALL ZDSCAL( K2-K1, SCAL, C( K1, LL ), 1 )
        !           789:                      END DO
        !           790:                   ENDIF
        !           791: *
        !           792:                   SCAL = ( SCAMIN / SWORK( I, L ) ) * SCALOC
        !           793:                   IF( SCAL .NE. ONE ) THEN
        !           794:                      DO LL = L1, L2-1
        !           795:                         CALL ZDSCAL( I2-I1, SCAL, C( I1, LL ), 1 )
        !           796:                      END DO
        !           797:                   ENDIF
        !           798: *
        !           799: *                 Record current scaling factor
        !           800: *
        !           801:                   SWORK( K, L ) = SCAMIN * SCALOC
        !           802:                   SWORK( I, L ) = SCAMIN * SCALOC
        !           803: *
        !           804:                   CALL ZGEMM( 'C', 'N', I2-I1, L2-L1, K2-K1, -CONE,
        !           805:      $                        A( K1, I1 ), LDA, C( K1, L1 ), LDC,
        !           806:      $                        CONE, C( I1, L1 ), LDC )
        !           807:                END DO
        !           808: *
        !           809:                DO J = 1, L - 1
        !           810: *
        !           811: *                 C( K, J ) := C( K, J ) - SGN * C( K, L ) * B( J, L )**H
        !           812: *
        !           813:                   J1 = (J - 1) * NB + 1
        !           814:                   J2 = MIN( J * NB, N ) + 1
        !           815: *
        !           816: *                 Compute scaling factor to survive the linear update
        !           817: *                 simulating consistent scaling.
        !           818: *
        !           819:                   CNRM = ZLANGE( 'I', K2-K1, J2-J1, C( K1, J1 ),
        !           820:      $                           LDC, WNRM )
        !           821:                   SCAMIN = MIN( SWORK( K, J ), SWORK( K, L ) )
        !           822:                   CNRM = CNRM * ( SCAMIN / SWORK( K, J ) )
        !           823:                   XNRM = XNRM * ( SCAMIN / SWORK( K, L ) )
        !           824:                   BNRM = SWORK( L, BWRK + J )
        !           825:                   SCALOC = DLARMM( BNRM, XNRM, CNRM )
        !           826:                   IF( SCALOC * SCAMIN .EQ. ZERO ) THEN
        !           827: *                    Use second scaling factor to prevent flushing to zero.
        !           828:                      BUF = BUF*2.D0**EXPONENT( SCALOC )
        !           829:                      DO JJ = 1, NBB
        !           830:                         DO LL = 1, NBA
        !           831:                         SWORK( LL, JJ ) = MIN( BIGNUM,
        !           832:      $                     SWORK( LL, JJ ) / 2.D0**EXPONENT( SCALOC ) )
        !           833:                         END DO
        !           834:                      END DO
        !           835:                      SCAMIN = SCAMIN / 2.D0**EXPONENT( SCALOC )
        !           836:                      SCALOC = SCALOC / 2.D0**EXPONENT( SCALOC )
        !           837:                   END IF
        !           838:                   CNRM = CNRM * SCALOC
        !           839:                   XNRM = XNRM * SCALOC
        !           840: *
        !           841: *                 Simultaneously apply the robust update factor and the
        !           842: *                 consistency scaling factor to C( K, J ) and C( K, L).
        !           843: *
        !           844:                   SCAL = ( SCAMIN / SWORK( K, L ) ) * SCALOC
        !           845:                   IF( SCAL .NE. ONE ) THEN
        !           846:                      DO LL = L1, L2-1
        !           847:                         CALL ZDSCAL( K2-K1, SCAL, C( K1, LL ), 1)
        !           848:                      END DO
        !           849:                   ENDIF
        !           850: *
        !           851:                   SCAL = ( SCAMIN / SWORK( K, J ) ) * SCALOC
        !           852:                   IF( SCAL .NE. ONE ) THEN
        !           853:                      DO JJ = J1, J2-1
        !           854:                         CALL ZDSCAL( K2-K1, SCAL, C( K1, JJ ), 1 )
        !           855:                      END DO
        !           856:                   ENDIF
        !           857: *
        !           858: *                 Record current scaling factor
        !           859: *
        !           860:                   SWORK( K, L ) = SCAMIN * SCALOC
        !           861:                   SWORK( K, J ) = SCAMIN * SCALOC
        !           862: *
        !           863:                   CALL ZGEMM( 'N', 'C', K2-K1, J2-J1, L2-L1, -CSGN,
        !           864:      $                        C( K1, L1 ), LDC, B( J1, L1 ), LDB,
        !           865:      $                        CONE, C( K1, J1 ), LDC )
        !           866:                END DO
        !           867:             END DO
        !           868:          END DO
        !           869:       ELSE IF( NOTRNA .AND. .NOT.NOTRNB ) THEN
        !           870: *
        !           871: *        Solve    A*X + ISGN*X*B**H = scale*C.
        !           872: *
        !           873: *        The (K,L)th block of X is determined starting from
        !           874: *        bottom-right corner column by column by
        !           875: *
        !           876: *            A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L)**H = C(K,L) - R(K,L)
        !           877: *
        !           878: *        Where
        !           879: *                      M                          N
        !           880: *            R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B(L,J)**H].
        !           881: *                    I=K+1                      J=L+1
        !           882: *
        !           883: *        Start loop over block rows (index = K) and block columns (index = L)
        !           884: *
        !           885:          DO K = NBA, 1, -1
        !           886: *
        !           887: *           K1: row index of the first row in X( K, L )
        !           888: *           K2: row index of the first row in X( K+1, L )
        !           889: *           so the K2 - K1 is the column count of the block X( K, L )
        !           890: *
        !           891:             K1 = (K - 1) * NB + 1
        !           892:             K2 = MIN( K * NB, M ) + 1
        !           893:             DO L = NBB, 1, -1
        !           894: *
        !           895: *              L1: column index of the first column in X( K, L )
        !           896: *              L2: column index of the first column in X( K, L + 1)
        !           897: *              so that L2 - L1 is the row count of the block X( K, L )
        !           898: *
        !           899:                L1 = (L - 1) * NB + 1
        !           900:                L2 = MIN( L * NB, N ) + 1
        !           901: *
        !           902:                CALL ZTRSYL( TRANA, TRANB, ISGN, K2-K1, L2-L1,
        !           903:      $                      A( K1, K1 ), LDA,
        !           904:      $                      B( L1, L1 ), LDB,
        !           905:      $                      C( K1, L1 ), LDC, SCALOC, IINFO )
        !           906:                INFO = MAX( INFO, IINFO )
        !           907: *
        !           908:                IF( SCALOC * SWORK( K, L ) .EQ. ZERO ) THEN
        !           909:                   IF( SCALOC .EQ. ZERO ) THEN
        !           910: *                    The magnitude of the largest entry of X(K1:K2-1, L1:L2-1)
        !           911: *                    is larger than the product of BIGNUM**2 and cannot be
        !           912: *                    represented in the form (1/SCALE)*X(K1:K2-1, L1:L2-1).
        !           913: *                    Mark the computation as pointless.
        !           914:                      BUF = ZERO
        !           915:                   ELSE
        !           916: *                    Use second scaling factor to prevent flushing to zero.
        !           917:                      BUF = BUF*2.D0**EXPONENT( SCALOC )
        !           918:                   END IF
        !           919:                   DO JJ = 1, NBB
        !           920:                      DO LL = 1, NBA
        !           921: *                       Bound by BIGNUM to not introduce Inf. The value
        !           922: *                       is irrelevant; corresponding entries of the
        !           923: *                       solution will be flushed in consistency scaling.
        !           924:                         SWORK( LL, JJ ) = MIN( BIGNUM,
        !           925:      $                     SWORK( LL, JJ ) / 2.D0**EXPONENT( SCALOC ) )
        !           926:                      END DO
        !           927:                   END DO
        !           928:                END IF
        !           929:                SWORK( K, L ) = SCALOC * SWORK( K, L )
        !           930:                XNRM = ZLANGE( 'I', K2-K1, L2-L1, C( K1, L1 ), LDC,
        !           931:      $                        WNRM )
        !           932: *
        !           933:                DO I = 1, K - 1
        !           934: *
        !           935: *                 C( I, L ) := C( I, L ) - A( I, K ) * C( K, L )
        !           936: *
        !           937:                   I1 = (I - 1) * NB + 1
        !           938:                   I2 = MIN( I * NB, M ) + 1
        !           939: *
        !           940: *                 Compute scaling factor to survive the linear update
        !           941: *                 simulating consistent scaling.
        !           942: *
        !           943:                   CNRM = ZLANGE( 'I', I2-I1, L2-L1, C( I1, L1 ),
        !           944:      $                           LDC, WNRM )
        !           945:                   SCAMIN = MIN( SWORK( I, L ), SWORK( K, L ) )
        !           946:                   CNRM = CNRM * ( SCAMIN / SWORK( I, L ) )
        !           947:                   XNRM = XNRM * ( SCAMIN / SWORK( K, L ) )
        !           948:                   ANRM = SWORK( I, AWRK + K )
        !           949:                   SCALOC = DLARMM( ANRM, XNRM, CNRM )
        !           950:                   IF( SCALOC * SCAMIN .EQ. ZERO ) THEN
        !           951: *                    Use second scaling factor to prevent flushing to zero.
        !           952:                      BUF = BUF*2.D0**EXPONENT( SCALOC )
        !           953:                      DO JJ = 1, NBB
        !           954:                         DO LL = 1, NBA
        !           955:                         SWORK( LL, JJ ) = MIN( BIGNUM,
        !           956:      $                     SWORK( LL, JJ ) / 2.D0**EXPONENT( SCALOC ) )
        !           957:                         END DO
        !           958:                      END DO
        !           959:                      SCAMIN = SCAMIN / 2.D0**EXPONENT( SCALOC )
        !           960:                      SCALOC = SCALOC / 2.D0**EXPONENT( SCALOC )
        !           961:                   END IF
        !           962:                   CNRM = CNRM * SCALOC
        !           963:                   XNRM = XNRM * SCALOC
        !           964: *
        !           965: *                 Simultaneously apply the robust update factor and the
        !           966: *                 consistency scaling factor to C( I, L ) and C( K, L).
        !           967: *
        !           968:                   SCAL = ( SCAMIN / SWORK( K, L ) ) * SCALOC
        !           969:                   IF( SCAL .NE. ONE ) THEN
        !           970:                      DO LL = L1, L2-1
        !           971:                         CALL ZDSCAL( K2-K1, SCAL, C( K1, LL ), 1 )
        !           972:                      END DO
        !           973:                   ENDIF
        !           974: *
        !           975:                   SCAL = ( SCAMIN / SWORK( I, L ) ) * SCALOC
        !           976:                   IF( SCAL .NE. ONE ) THEN
        !           977:                      DO LL = L1, L2-1
        !           978:                         CALL ZDSCAL( I2-I1, SCAL, C( I1, LL ), 1 )
        !           979:                      END DO
        !           980:                   ENDIF
        !           981: *
        !           982: *                 Record current scaling factor
        !           983: *
        !           984:                   SWORK( K, L ) = SCAMIN * SCALOC
        !           985:                   SWORK( I, L ) = SCAMIN * SCALOC
        !           986: *
        !           987:                   CALL ZGEMM( 'N', 'N', I2-I1, L2-L1, K2-K1, -CONE,
        !           988:      $                        A( I1, K1 ), LDA, C( K1, L1 ), LDC,
        !           989:      $                        CONE, C( I1, L1 ), LDC )
        !           990: *
        !           991:                END DO
        !           992: *
        !           993:                DO J = 1, L - 1
        !           994: *
        !           995: *                 C( K, J ) := C( K, J ) - SGN * C( K, L ) * B( J, L )**H
        !           996: *
        !           997:                   J1 = (J - 1) * NB + 1
        !           998:                   J2 = MIN( J * NB, N ) + 1
        !           999: *
        !          1000: *                 Compute scaling factor to survive the linear update
        !          1001: *                 simulating consistent scaling.
        !          1002: *
        !          1003:                   CNRM = ZLANGE( 'I', K2-K1, J2-J1, C( K1, J1 ),
        !          1004:      $                           LDC, WNRM )
        !          1005:                   SCAMIN = MIN( SWORK( K, J ), SWORK( K, L ) )
        !          1006:                   CNRM = CNRM * ( SCAMIN / SWORK( K, J ) )
        !          1007:                   XNRM = XNRM * ( SCAMIN / SWORK( K, L ) )
        !          1008:                   BNRM = SWORK( L, BWRK + J )
        !          1009:                   SCALOC = DLARMM( BNRM, XNRM, CNRM )
        !          1010:                   IF( SCALOC * SCAMIN .EQ. ZERO ) THEN
        !          1011: *                    Use second scaling factor to prevent flushing to zero.
        !          1012:                      BUF = BUF*2.D0**EXPONENT( SCALOC )
        !          1013:                      DO JJ = 1, NBB
        !          1014:                         DO LL = 1, NBA
        !          1015:                         SWORK( LL, JJ ) = MIN( BIGNUM,
        !          1016:      $                     SWORK( LL, JJ ) / 2.D0**EXPONENT( SCALOC ) )
        !          1017:                         END DO
        !          1018:                      END DO
        !          1019:                      SCAMIN = SCAMIN / 2.D0**EXPONENT( SCALOC )
        !          1020:                      SCALOC = SCALOC / 2.D0**EXPONENT( SCALOC )
        !          1021:                   END IF
        !          1022:                   CNRM = CNRM * SCALOC
        !          1023:                   XNRM = XNRM * SCALOC
        !          1024: *
        !          1025: *                 Simultaneously apply the robust update factor and the
        !          1026: *                 consistency scaling factor to C( K, J ) and C( K, L).
        !          1027: *
        !          1028:                   SCAL = ( SCAMIN / SWORK( K, L ) ) * SCALOC
        !          1029:                   IF( SCAL .NE. ONE ) THEN
        !          1030:                      DO JJ = L1, L2-1
        !          1031:                         CALL ZDSCAL( K2-K1, SCAL, C( K1, JJ ), 1 )
        !          1032:                      END DO
        !          1033:                   ENDIF
        !          1034: *
        !          1035:                   SCAL = ( SCAMIN / SWORK( K, J ) ) * SCALOC
        !          1036:                   IF( SCAL .NE. ONE ) THEN
        !          1037:                      DO JJ = J1, J2-1
        !          1038:                         CALL ZDSCAL( K2-K1, SCAL, C( K1, JJ ), 1 )
        !          1039:                      END DO
        !          1040:                   ENDIF
        !          1041: *
        !          1042: *                 Record current scaling factor
        !          1043: *
        !          1044:                   SWORK( K, L ) = SCAMIN * SCALOC
        !          1045:                   SWORK( K, J ) = SCAMIN * SCALOC
        !          1046: *
        !          1047:                   CALL ZGEMM( 'N', 'C', K2-K1, J2-J1, L2-L1, -CSGN,
        !          1048:      $                        C( K1, L1 ), LDC, B( J1, L1 ), LDB,
        !          1049:      $                        CONE, C( K1, J1 ), LDC )
        !          1050:                END DO
        !          1051:             END DO
        !          1052:          END DO
        !          1053: *
        !          1054:       END IF
        !          1055: *
        !          1056: *     Reduce local scaling factors
        !          1057: *
        !          1058:       SCALE = SWORK( 1, 1 )
        !          1059:       DO K = 1, NBA
        !          1060:          DO L = 1, NBB
        !          1061:             SCALE = MIN( SCALE, SWORK( K, L ) )
        !          1062:          END DO
        !          1063:       END DO
        !          1064:       IF( SCALE .EQ. ZERO ) THEN
        !          1065: *
        !          1066: *        The magnitude of the largest entry of the solution is larger
        !          1067: *        than the product of BIGNUM**2 and cannot be represented in the
        !          1068: *        form (1/SCALE)*X if SCALE is DOUBLE PRECISION. Set SCALE to
        !          1069: *        zero and give up.
        !          1070: *
        !          1071:          SWORK(1,1) = MAX( NBA, NBB )
        !          1072:          SWORK(2,1) = 2 * NBB + NBA
        !          1073:          RETURN
        !          1074:       END IF
        !          1075: *
        !          1076: *     Realize consistent scaling
        !          1077: *
        !          1078:       DO K = 1, NBA
        !          1079:          K1 = (K - 1) * NB + 1
        !          1080:          K2 = MIN( K * NB, M ) + 1
        !          1081:          DO L = 1, NBB
        !          1082:             L1 = (L - 1) * NB + 1
        !          1083:             L2 = MIN( L * NB, N ) + 1
        !          1084:             SCAL = SCALE / SWORK( K, L )
        !          1085:             IF( SCAL .NE. ONE ) THEN
        !          1086:                DO LL = L1, L2-1
        !          1087:                   CALL ZDSCAL( K2-K1, SCAL, C( K1, LL ), 1 )
        !          1088:                END DO
        !          1089:             ENDIF
        !          1090:          END DO
        !          1091:       END DO
        !          1092: *
        !          1093:       IF( BUF .NE. ONE .AND. BUF.GT.ZERO ) THEN
        !          1094: *
        !          1095: *        Decrease SCALE as much as possible.
        !          1096: *
        !          1097:          SCALOC = MIN( SCALE / SMLNUM, ONE / BUF )
        !          1098:          BUF = BUF * SCALOC
        !          1099:          SCALE = SCALE / SCALOC
        !          1100:       END IF
        !          1101: *
        !          1102:       IF( BUF.NE.ONE .AND. BUF.GT.ZERO ) THEN
        !          1103: *
        !          1104: *        In case of overly aggressive scaling during the computation,
        !          1105: *        flushing of the global scale factor may be prevented by
        !          1106: *        undoing some of the scaling. This step is to ensure that
        !          1107: *        this routine flushes only scale factors that TRSYL also
        !          1108: *        flushes and be usable as a drop-in replacement.
        !          1109: *
        !          1110: *        How much can the normwise largest entry be upscaled?
        !          1111: *
        !          1112:          SCAL = MAX( ABS( DBLE( C( 1, 1 ) ) ),
        !          1113:      $               ABS( DIMAG( C ( 1, 1 ) ) ) )
        !          1114:          DO K = 1, M
        !          1115:             DO L = 1, N
        !          1116:                SCAL = MAX( SCAL, ABS( DBLE ( C( K, L ) ) ),
        !          1117:      $                     ABS( DIMAG ( C( K, L ) ) ) )
        !          1118:             END DO
        !          1119:          END DO
        !          1120: *
        !          1121: *        Increase BUF as close to 1 as possible and apply scaling.
        !          1122: *
        !          1123:          SCALOC = MIN( BIGNUM / SCAL, ONE / BUF )
        !          1124:          BUF = BUF * SCALOC
        !          1125:          CALL ZLASCL( 'G', -1, -1, ONE, SCALOC, M, N, C, LDC, IINFO )
        !          1126:       END IF
        !          1127: *
        !          1128: *     Combine with buffer scaling factor. SCALE will be flushed if
        !          1129: *     BUF is less than one here.
        !          1130: *
        !          1131:       SCALE = SCALE * BUF
        !          1132: *
        !          1133: *     Restore workspace dimensions
        !          1134: *
        !          1135:       SWORK(1,1) = MAX( NBA, NBB )
        !          1136:       SWORK(2,1) = 2 * NBB + NBA
        !          1137: *
        !          1138:       RETURN
        !          1139: *
        !          1140: *     End of ZTRSYL3
        !          1141: *
        !          1142:       END

CVSweb interface <joel.bertrand@systella.fr>