LAPACK 3.3.1 Linear Algebra PACKage

# dtgsyl.f

Go to the documentation of this file.
```00001       SUBROUTINE DTGSYL( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D,
00002      \$                   LDD, E, LDE, F, LDF, SCALE, DIF, WORK, LWORK,
00003      \$                   IWORK, INFO )
00004 *
00005 *  -- LAPACK routine (version 3.3.1) --
00006 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00007 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00008 *  -- April 2011                                                      --
00009 *
00010 *     .. Scalar Arguments ..
00011       CHARACTER          TRANS
00012       INTEGER            IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF,
00013      \$                   LWORK, M, N
00014       DOUBLE PRECISION   DIF, SCALE
00015 *     ..
00016 *     .. Array Arguments ..
00017       INTEGER            IWORK( * )
00018       DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), C( LDC, * ),
00019      \$                   D( LDD, * ), E( LDE, * ), F( LDF, * ),
00020      \$                   WORK( * )
00021 *     ..
00022 *
00023 *  Purpose
00024 *  =======
00025 *
00026 *  DTGSYL solves the generalized Sylvester equation:
00027 *
00028 *              A * R - L * B = scale * C                 (1)
00029 *              D * R - L * E = scale * F
00030 *
00031 *  where R and L are unknown m-by-n matrices, (A, D), (B, E) and
00032 *  (C, F) are given matrix pairs of size m-by-m, n-by-n and m-by-n,
00033 *  respectively, with real entries. (A, D) and (B, E) must be in
00034 *  generalized (real) Schur canonical form, i.e. A, B are upper quasi
00035 *  triangular and D, E are upper triangular.
00036 *
00037 *  The solution (R, L) overwrites (C, F). 0 <= SCALE <= 1 is an output
00038 *  scaling factor chosen to avoid overflow.
00039 *
00040 *  In matrix notation (1) is equivalent to solve  Zx = scale b, where
00041 *  Z is defined as
00042 *
00043 *             Z = [ kron(In, A)  -kron(B**T, Im) ]         (2)
00044 *                 [ kron(In, D)  -kron(E**T, Im) ].
00045 *
00046 *  Here Ik is the identity matrix of size k and X**T is the transpose of
00047 *  X. kron(X, Y) is the Kronecker product between the matrices X and Y.
00048 *
00049 *  If TRANS = 'T', DTGSYL solves the transposed system Z**T*y = scale*b,
00050 *  which is equivalent to solve for R and L in
00051 *
00052 *              A**T * R + D**T * L = scale * C           (3)
00053 *              R * B**T + L * E**T = scale * -F
00054 *
00055 *  This case (TRANS = 'T') is used to compute an one-norm-based estimate
00056 *  of Dif[(A,D), (B,E)], the separation between the matrix pairs (A,D)
00057 *  and (B,E), using DLACON.
00058 *
00059 *  If IJOB >= 1, DTGSYL computes a Frobenius norm-based estimate
00060 *  of Dif[(A,D),(B,E)]. That is, the reciprocal of a lower bound on the
00061 *  reciprocal of the smallest singular value of Z. See [1-2] for more
00062 *  information.
00063 *
00064 *  This is a level 3 BLAS algorithm.
00065 *
00066 *  Arguments
00067 *  =========
00068 *
00069 *  TRANS   (input) CHARACTER*1
00070 *          = 'N', solve the generalized Sylvester equation (1).
00071 *          = 'T', solve the 'transposed' system (3).
00072 *
00073 *  IJOB    (input) INTEGER
00074 *          Specifies what kind of functionality to be performed.
00075 *           =0: solve (1) only.
00076 *           =1: The functionality of 0 and 3.
00077 *           =2: The functionality of 0 and 4.
00078 *           =3: Only an estimate of Dif[(A,D), (B,E)] is computed.
00079 *               (look ahead strategy IJOB  = 1 is used).
00080 *           =4: Only an estimate of Dif[(A,D), (B,E)] is computed.
00081 *               ( DGECON on sub-systems is used ).
00082 *          Not referenced if TRANS = 'T'.
00083 *
00084 *  M       (input) INTEGER
00085 *          The order of the matrices A and D, and the row dimension of
00086 *          the matrices C, F, R and L.
00087 *
00088 *  N       (input) INTEGER
00089 *          The order of the matrices B and E, and the column dimension
00090 *          of the matrices C, F, R and L.
00091 *
00092 *  A       (input) DOUBLE PRECISION array, dimension (LDA, M)
00093 *          The upper quasi triangular matrix A.
00094 *
00095 *  LDA     (input) INTEGER
00096 *          The leading dimension of the array A. LDA >= max(1, M).
00097 *
00098 *  B       (input) DOUBLE PRECISION array, dimension (LDB, N)
00099 *          The upper quasi triangular matrix B.
00100 *
00101 *  LDB     (input) INTEGER
00102 *          The leading dimension of the array B. LDB >= max(1, N).
00103 *
00104 *  C       (input/output) DOUBLE PRECISION array, dimension (LDC, N)
00105 *          On entry, C contains the right-hand-side of the first matrix
00106 *          equation in (1) or (3).
00107 *          On exit, if IJOB = 0, 1 or 2, C has been overwritten by
00108 *          the solution R. If IJOB = 3 or 4 and TRANS = 'N', C holds R,
00109 *          the solution achieved during the computation of the
00110 *          Dif-estimate.
00111 *
00112 *  LDC     (input) INTEGER
00113 *          The leading dimension of the array C. LDC >= max(1, M).
00114 *
00115 *  D       (input) DOUBLE PRECISION array, dimension (LDD, M)
00116 *          The upper triangular matrix D.
00117 *
00118 *  LDD     (input) INTEGER
00119 *          The leading dimension of the array D. LDD >= max(1, M).
00120 *
00121 *  E       (input) DOUBLE PRECISION array, dimension (LDE, N)
00122 *          The upper triangular matrix E.
00123 *
00124 *  LDE     (input) INTEGER
00125 *          The leading dimension of the array E. LDE >= max(1, N).
00126 *
00127 *  F       (input/output) DOUBLE PRECISION array, dimension (LDF, N)
00128 *          On entry, F contains the right-hand-side of the second matrix
00129 *          equation in (1) or (3).
00130 *          On exit, if IJOB = 0, 1 or 2, F has been overwritten by
00131 *          the solution L. If IJOB = 3 or 4 and TRANS = 'N', F holds L,
00132 *          the solution achieved during the computation of the
00133 *          Dif-estimate.
00134 *
00135 *  LDF     (input) INTEGER
00136 *          The leading dimension of the array F. LDF >= max(1, M).
00137 *
00138 *  DIF     (output) DOUBLE PRECISION
00139 *          On exit DIF is the reciprocal of a lower bound of the
00140 *          reciprocal of the Dif-function, i.e. DIF is an upper bound of
00141 *          Dif[(A,D), (B,E)] = sigma_min(Z), where Z as in (2).
00142 *          IF IJOB = 0 or TRANS = 'T', DIF is not touched.
00143 *
00144 *  SCALE   (output) DOUBLE PRECISION
00145 *          On exit SCALE is the scaling factor in (1) or (3).
00146 *          If 0 < SCALE < 1, C and F hold the solutions R and L, resp.,
00147 *          to a slightly perturbed system but the input matrices A, B, D
00148 *          and E have not been changed. If SCALE = 0, C and F hold the
00149 *          solutions R and L, respectively, to the homogeneous system
00150 *          with C = F = 0. Normally, SCALE = 1.
00151 *
00152 *  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
00153 *          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
00154 *
00155 *  LWORK   (input) INTEGER
00156 *          The dimension of the array WORK. LWORK > = 1.
00157 *          If IJOB = 1 or 2 and TRANS = 'N', LWORK >= max(1,2*M*N).
00158 *
00159 *          If LWORK = -1, then a workspace query is assumed; the routine
00160 *          only calculates the optimal size of the WORK array, returns
00161 *          this value as the first entry of the WORK array, and no error
00162 *          message related to LWORK is issued by XERBLA.
00163 *
00164 *  IWORK   (workspace) INTEGER array, dimension (M+N+6)
00165 *
00166 *  INFO    (output) INTEGER
00167 *            =0: successful exit
00168 *            <0: If INFO = -i, the i-th argument had an illegal value.
00169 *            >0: (A, D) and (B, E) have common or close eigenvalues.
00170 *
00171 *  Further Details
00172 *  ===============
00173 *
00174 *  Based on contributions by
00175 *     Bo Kagstrom and Peter Poromaa, Department of Computing Science,
00176 *     Umea University, S-901 87 Umea, Sweden.
00177 *
00178 *  [1] B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software
00179 *      for Solving the Generalized Sylvester Equation and Estimating the
00180 *      Separation between Regular Matrix Pairs, Report UMINF - 93.23,
00181 *      Department of Computing Science, Umea University, S-901 87 Umea,
00182 *      Sweden, December 1993, Revised April 1994, Also as LAPACK Working
00183 *      Note 75.  To appear in ACM Trans. on Math. Software, Vol 22,
00184 *      No 1, 1996.
00185 *
00186 *  [2] B. Kagstrom, A Perturbation Analysis of the Generalized Sylvester
00187 *      Equation (AR - LB, DR - LE ) = (C, F), SIAM J. Matrix Anal.
00188 *      Appl., 15(4):1045-1060, 1994
00189 *
00190 *  [3] B. Kagstrom and L. Westin, Generalized Schur Methods with
00191 *      Condition Estimators for Solving the Generalized Sylvester
00192 *      Equation, IEEE Transactions on Automatic Control, Vol. 34, No. 7,
00193 *      July 1989, pp 745-751.
00194 *
00195 *  =====================================================================
00196 *  Replaced various illegal calls to DCOPY by calls to DLASET.
00197 *  Sven Hammarling, 1/5/02.
00198 *
00199 *     .. Parameters ..
00200       DOUBLE PRECISION   ZERO, ONE
00201       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
00202 *     ..
00203 *     .. Local Scalars ..
00204       LOGICAL            LQUERY, NOTRAN
00205       INTEGER            I, IE, IFUNC, IROUND, IS, ISOLVE, J, JE, JS, K,
00206      \$                   LINFO, LWMIN, MB, NB, P, PPQQ, PQ, Q
00207       DOUBLE PRECISION   DSCALE, DSUM, SCALE2, SCALOC
00208 *     ..
00209 *     .. External Functions ..
00210       LOGICAL            LSAME
00211       INTEGER            ILAENV
00212       EXTERNAL           LSAME, ILAENV
00213 *     ..
00214 *     .. External Subroutines ..
00215       EXTERNAL           DGEMM, DLACPY, DLASET, DSCAL, DTGSY2, XERBLA
00216 *     ..
00217 *     .. Intrinsic Functions ..
00218       INTRINSIC          DBLE, MAX, SQRT
00219 *     ..
00220 *     .. Executable Statements ..
00221 *
00222 *     Decode and test input parameters
00223 *
00224       INFO = 0
00225       NOTRAN = LSAME( TRANS, 'N' )
00226       LQUERY = ( LWORK.EQ.-1 )
00227 *
00228       IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
00229          INFO = -1
00230       ELSE IF( NOTRAN ) THEN
00231          IF( ( IJOB.LT.0 ) .OR. ( IJOB.GT.4 ) ) THEN
00232             INFO = -2
00233          END IF
00234       END IF
00235       IF( INFO.EQ.0 ) THEN
00236          IF( M.LE.0 ) THEN
00237             INFO = -3
00238          ELSE IF( N.LE.0 ) THEN
00239             INFO = -4
00240          ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
00241             INFO = -6
00242          ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00243             INFO = -8
00244          ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
00245             INFO = -10
00246          ELSE IF( LDD.LT.MAX( 1, M ) ) THEN
00247             INFO = -12
00248          ELSE IF( LDE.LT.MAX( 1, N ) ) THEN
00249             INFO = -14
00250          ELSE IF( LDF.LT.MAX( 1, M ) ) THEN
00251             INFO = -16
00252          END IF
00253       END IF
00254 *
00255       IF( INFO.EQ.0 ) THEN
00256          IF( NOTRAN ) THEN
00257             IF( IJOB.EQ.1 .OR. IJOB.EQ.2 ) THEN
00258                LWMIN = MAX( 1, 2*M*N )
00259             ELSE
00260                LWMIN = 1
00261             END IF
00262          ELSE
00263             LWMIN = 1
00264          END IF
00265          WORK( 1 ) = LWMIN
00266 *
00267          IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
00268             INFO = -20
00269          END IF
00270       END IF
00271 *
00272       IF( INFO.NE.0 ) THEN
00273          CALL XERBLA( 'DTGSYL', -INFO )
00274          RETURN
00275       ELSE IF( LQUERY ) THEN
00276          RETURN
00277       END IF
00278 *
00279 *     Quick return if possible
00280 *
00281       IF( M.EQ.0 .OR. N.EQ.0 ) THEN
00282          SCALE = 1
00283          IF( NOTRAN ) THEN
00284             IF( IJOB.NE.0 ) THEN
00285                DIF = 0
00286             END IF
00287          END IF
00288          RETURN
00289       END IF
00290 *
00291 *     Determine optimal block sizes MB and NB
00292 *
00293       MB = ILAENV( 2, 'DTGSYL', TRANS, M, N, -1, -1 )
00294       NB = ILAENV( 5, 'DTGSYL', TRANS, M, N, -1, -1 )
00295 *
00296       ISOLVE = 1
00297       IFUNC = 0
00298       IF( NOTRAN ) THEN
00299          IF( IJOB.GE.3 ) THEN
00300             IFUNC = IJOB - 2
00301             CALL DLASET( 'F', M, N, ZERO, ZERO, C, LDC )
00302             CALL DLASET( 'F', M, N, ZERO, ZERO, F, LDF )
00303          ELSE IF( IJOB.GE.1 ) THEN
00304             ISOLVE = 2
00305          END IF
00306       END IF
00307 *
00308       IF( ( MB.LE.1 .AND. NB.LE.1 ) .OR. ( MB.GE.M .AND. NB.GE.N ) )
00309      \$     THEN
00310 *
00311          DO 30 IROUND = 1, ISOLVE
00312 *
00313 *           Use unblocked Level 2 solver
00314 *
00315             DSCALE = ZERO
00316             DSUM = ONE
00317             PQ = 0
00318             CALL DTGSY2( TRANS, IFUNC, M, N, A, LDA, B, LDB, C, LDC, D,
00319      \$                   LDD, E, LDE, F, LDF, SCALE, DSUM, DSCALE,
00320      \$                   IWORK, PQ, INFO )
00321             IF( DSCALE.NE.ZERO ) THEN
00322                IF( IJOB.EQ.1 .OR. IJOB.EQ.3 ) THEN
00323                   DIF = SQRT( DBLE( 2*M*N ) ) / ( DSCALE*SQRT( DSUM ) )
00324                ELSE
00325                   DIF = SQRT( DBLE( PQ ) ) / ( DSCALE*SQRT( DSUM ) )
00326                END IF
00327             END IF
00328 *
00329             IF( ISOLVE.EQ.2 .AND. IROUND.EQ.1 ) THEN
00330                IF( NOTRAN ) THEN
00331                   IFUNC = IJOB
00332                END IF
00333                SCALE2 = SCALE
00334                CALL DLACPY( 'F', M, N, C, LDC, WORK, M )
00335                CALL DLACPY( 'F', M, N, F, LDF, WORK( M*N+1 ), M )
00336                CALL DLASET( 'F', M, N, ZERO, ZERO, C, LDC )
00337                CALL DLASET( 'F', M, N, ZERO, ZERO, F, LDF )
00338             ELSE IF( ISOLVE.EQ.2 .AND. IROUND.EQ.2 ) THEN
00339                CALL DLACPY( 'F', M, N, WORK, M, C, LDC )
00340                CALL DLACPY( 'F', M, N, WORK( M*N+1 ), M, F, LDF )
00341                SCALE = SCALE2
00342             END IF
00343    30    CONTINUE
00344 *
00345          RETURN
00346       END IF
00347 *
00348 *     Determine block structure of A
00349 *
00350       P = 0
00351       I = 1
00352    40 CONTINUE
00353       IF( I.GT.M )
00354      \$   GO TO 50
00355       P = P + 1
00356       IWORK( P ) = I
00357       I = I + MB
00358       IF( I.GE.M )
00359      \$   GO TO 50
00360       IF( A( I, I-1 ).NE.ZERO )
00361      \$   I = I + 1
00362       GO TO 40
00363    50 CONTINUE
00364 *
00365       IWORK( P+1 ) = M + 1
00366       IF( IWORK( P ).EQ.IWORK( P+1 ) )
00367      \$   P = P - 1
00368 *
00369 *     Determine block structure of B
00370 *
00371       Q = P + 1
00372       J = 1
00373    60 CONTINUE
00374       IF( J.GT.N )
00375      \$   GO TO 70
00376       Q = Q + 1
00377       IWORK( Q ) = J
00378       J = J + NB
00379       IF( J.GE.N )
00380      \$   GO TO 70
00381       IF( B( J, J-1 ).NE.ZERO )
00382      \$   J = J + 1
00383       GO TO 60
00384    70 CONTINUE
00385 *
00386       IWORK( Q+1 ) = N + 1
00387       IF( IWORK( Q ).EQ.IWORK( Q+1 ) )
00388      \$   Q = Q - 1
00389 *
00390       IF( NOTRAN ) THEN
00391 *
00392          DO 150 IROUND = 1, ISOLVE
00393 *
00394 *           Solve (I, J)-subsystem
00395 *               A(I, I) * R(I, J) - L(I, J) * B(J, J) = C(I, J)
00396 *               D(I, I) * R(I, J) - L(I, J) * E(J, J) = F(I, J)
00397 *           for I = P, P - 1,..., 1; J = 1, 2,..., Q
00398 *
00399             DSCALE = ZERO
00400             DSUM = ONE
00401             PQ = 0
00402             SCALE = ONE
00403             DO 130 J = P + 2, Q
00404                JS = IWORK( J )
00405                JE = IWORK( J+1 ) - 1
00406                NB = JE - JS + 1
00407                DO 120 I = P, 1, -1
00408                   IS = IWORK( I )
00409                   IE = IWORK( I+1 ) - 1
00410                   MB = IE - IS + 1
00411                   PPQQ = 0
00412                   CALL DTGSY2( TRANS, IFUNC, MB, NB, A( IS, IS ), LDA,
00413      \$                         B( JS, JS ), LDB, C( IS, JS ), LDC,
00414      \$                         D( IS, IS ), LDD, E( JS, JS ), LDE,
00415      \$                         F( IS, JS ), LDF, SCALOC, DSUM, DSCALE,
00416      \$                         IWORK( Q+2 ), PPQQ, LINFO )
00417                   IF( LINFO.GT.0 )
00418      \$               INFO = LINFO
00419 *
00420                   PQ = PQ + PPQQ
00421                   IF( SCALOC.NE.ONE ) THEN
00422                      DO 80 K = 1, JS - 1
00423                         CALL DSCAL( M, SCALOC, C( 1, K ), 1 )
00424                         CALL DSCAL( M, SCALOC, F( 1, K ), 1 )
00425    80                CONTINUE
00426                      DO 90 K = JS, JE
00427                         CALL DSCAL( IS-1, SCALOC, C( 1, K ), 1 )
00428                         CALL DSCAL( IS-1, SCALOC, F( 1, K ), 1 )
00429    90                CONTINUE
00430                      DO 100 K = JS, JE
00431                         CALL DSCAL( M-IE, SCALOC, C( IE+1, K ), 1 )
00432                         CALL DSCAL( M-IE, SCALOC, F( IE+1, K ), 1 )
00433   100                CONTINUE
00434                      DO 110 K = JE + 1, N
00435                         CALL DSCAL( M, SCALOC, C( 1, K ), 1 )
00436                         CALL DSCAL( M, SCALOC, F( 1, K ), 1 )
00437   110                CONTINUE
00438                      SCALE = SCALE*SCALOC
00439                   END IF
00440 *
00441 *                 Substitute R(I, J) and L(I, J) into remaining
00442 *                 equation.
00443 *
00444                   IF( I.GT.1 ) THEN
00445                      CALL DGEMM( 'N', 'N', IS-1, NB, MB, -ONE,
00446      \$                           A( 1, IS ), LDA, C( IS, JS ), LDC, ONE,
00447      \$                           C( 1, JS ), LDC )
00448                      CALL DGEMM( 'N', 'N', IS-1, NB, MB, -ONE,
00449      \$                           D( 1, IS ), LDD, C( IS, JS ), LDC, ONE,
00450      \$                           F( 1, JS ), LDF )
00451                   END IF
00452                   IF( J.LT.Q ) THEN
00453                      CALL DGEMM( 'N', 'N', MB, N-JE, NB, ONE,
00454      \$                           F( IS, JS ), LDF, B( JS, JE+1 ), LDB,
00455      \$                           ONE, C( IS, JE+1 ), LDC )
00456                      CALL DGEMM( 'N', 'N', MB, N-JE, NB, ONE,
00457      \$                           F( IS, JS ), LDF, E( JS, JE+1 ), LDE,
00458      \$                           ONE, F( IS, JE+1 ), LDF )
00459                   END IF
00460   120          CONTINUE
00461   130       CONTINUE
00462             IF( DSCALE.NE.ZERO ) THEN
00463                IF( IJOB.EQ.1 .OR. IJOB.EQ.3 ) THEN
00464                   DIF = SQRT( DBLE( 2*M*N ) ) / ( DSCALE*SQRT( DSUM ) )
00465                ELSE
00466                   DIF = SQRT( DBLE( PQ ) ) / ( DSCALE*SQRT( DSUM ) )
00467                END IF
00468             END IF
00469             IF( ISOLVE.EQ.2 .AND. IROUND.EQ.1 ) THEN
00470                IF( NOTRAN ) THEN
00471                   IFUNC = IJOB
00472                END IF
00473                SCALE2 = SCALE
00474                CALL DLACPY( 'F', M, N, C, LDC, WORK, M )
00475                CALL DLACPY( 'F', M, N, F, LDF, WORK( M*N+1 ), M )
00476                CALL DLASET( 'F', M, N, ZERO, ZERO, C, LDC )
00477                CALL DLASET( 'F', M, N, ZERO, ZERO, F, LDF )
00478             ELSE IF( ISOLVE.EQ.2 .AND. IROUND.EQ.2 ) THEN
00479                CALL DLACPY( 'F', M, N, WORK, M, C, LDC )
00480                CALL DLACPY( 'F', M, N, WORK( M*N+1 ), M, F, LDF )
00481                SCALE = SCALE2
00482             END IF
00483   150    CONTINUE
00484 *
00485       ELSE
00486 *
00487 *        Solve transposed (I, J)-subsystem
00488 *             A(I, I)**T * R(I, J)  + D(I, I)**T * L(I, J)  =  C(I, J)
00489 *             R(I, J)  * B(J, J)**T + L(I, J)  * E(J, J)**T = -F(I, J)
00490 *        for I = 1,2,..., P; J = Q, Q-1,..., 1
00491 *
00492          SCALE = ONE
00493          DO 210 I = 1, P
00494             IS = IWORK( I )
00495             IE = IWORK( I+1 ) - 1
00496             MB = IE - IS + 1
00497             DO 200 J = Q, P + 2, -1
00498                JS = IWORK( J )
00499                JE = IWORK( J+1 ) - 1
00500                NB = JE - JS + 1
00501                CALL DTGSY2( TRANS, IFUNC, MB, NB, A( IS, IS ), LDA,
00502      \$                      B( JS, JS ), LDB, C( IS, JS ), LDC,
00503      \$                      D( IS, IS ), LDD, E( JS, JS ), LDE,
00504      \$                      F( IS, JS ), LDF, SCALOC, DSUM, DSCALE,
00505      \$                      IWORK( Q+2 ), PPQQ, LINFO )
00506                IF( LINFO.GT.0 )
00507      \$            INFO = LINFO
00508                IF( SCALOC.NE.ONE ) THEN
00509                   DO 160 K = 1, JS - 1
00510                      CALL DSCAL( M, SCALOC, C( 1, K ), 1 )
00511                      CALL DSCAL( M, SCALOC, F( 1, K ), 1 )
00512   160             CONTINUE
00513                   DO 170 K = JS, JE
00514                      CALL DSCAL( IS-1, SCALOC, C( 1, K ), 1 )
00515                      CALL DSCAL( IS-1, SCALOC, F( 1, K ), 1 )
00516   170             CONTINUE
00517                   DO 180 K = JS, JE
00518                      CALL DSCAL( M-IE, SCALOC, C( IE+1, K ), 1 )
00519                      CALL DSCAL( M-IE, SCALOC, F( IE+1, K ), 1 )
00520   180             CONTINUE
00521                   DO 190 K = JE + 1, N
00522                      CALL DSCAL( M, SCALOC, C( 1, K ), 1 )
00523                      CALL DSCAL( M, SCALOC, F( 1, K ), 1 )
00524   190             CONTINUE
00525                   SCALE = SCALE*SCALOC
00526                END IF
00527 *
00528 *              Substitute R(I, J) and L(I, J) into remaining equation.
00529 *
00530                IF( J.GT.P+2 ) THEN
00531                   CALL DGEMM( 'N', 'T', MB, JS-1, NB, ONE, C( IS, JS ),
00532      \$                        LDC, B( 1, JS ), LDB, ONE, F( IS, 1 ),
00533      \$                        LDF )
00534                   CALL DGEMM( 'N', 'T', MB, JS-1, NB, ONE, F( IS, JS ),
00535      \$                        LDF, E( 1, JS ), LDE, ONE, F( IS, 1 ),
00536      \$                        LDF )
00537                END IF
00538                IF( I.LT.P ) THEN
00539                   CALL DGEMM( 'T', 'N', M-IE, NB, MB, -ONE,
00540      \$                        A( IS, IE+1 ), LDA, C( IS, JS ), LDC, ONE,
00541      \$                        C( IE+1, JS ), LDC )
00542                   CALL DGEMM( 'T', 'N', M-IE, NB, MB, -ONE,
00543      \$                        D( IS, IE+1 ), LDD, F( IS, JS ), LDF, ONE,
00544      \$                        C( IE+1, JS ), LDC )
00545                END IF
00546   200       CONTINUE
00547   210    CONTINUE
00548 *
00549       END IF
00550 *
00551       WORK( 1 ) = LWMIN
00552 *
00553       RETURN
00554 *
00555 *     End of DTGSYL
00556 *
00557       END
```