LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
dtgsyl.f
Go to the documentation of this file.
1*> \brief \b DTGSYL
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download DTGSYL + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtgsyl.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtgsyl.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtgsyl.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE DTGSYL( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D,
20* LDD, E, LDE, F, LDF, SCALE, DIF, WORK, LWORK,
21* IWORK, INFO )
22*
23* .. Scalar Arguments ..
24* CHARACTER TRANS
25* INTEGER IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF,
26* $ LWORK, M, N
27* DOUBLE PRECISION DIF, SCALE
28* ..
29* .. Array Arguments ..
30* INTEGER IWORK( * )
31* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ),
32* $ D( LDD, * ), E( LDE, * ), F( LDF, * ),
33* $ WORK( * )
34* ..
35*
36*
37*> \par Purpose:
38* =============
39*>
40*> \verbatim
41*>
42*> DTGSYL solves the generalized Sylvester equation:
43*>
44*> A * R - L * B = scale * C (1)
45*> D * R - L * E = scale * F
46*>
47*> where R and L are unknown m-by-n matrices, (A, D), (B, E) and
48*> (C, F) are given matrix pairs of size m-by-m, n-by-n and m-by-n,
49*> respectively, with real entries. (A, D) and (B, E) must be in
50*> generalized (real) Schur canonical form, i.e. A, B are upper quasi
51*> triangular and D, E are upper triangular.
52*>
53*> The solution (R, L) overwrites (C, F). 0 <= SCALE <= 1 is an output
54*> scaling factor chosen to avoid overflow.
55*>
56*> In matrix notation (1) is equivalent to solve Zx = scale b, where
57*> Z is defined as
58*>
59*> Z = [ kron(In, A) -kron(B**T, Im) ] (2)
60*> [ kron(In, D) -kron(E**T, Im) ].
61*>
62*> Here Ik is the identity matrix of size k and X**T is the transpose of
63*> X. kron(X, Y) is the Kronecker product between the matrices X and Y.
64*>
65*> If TRANS = 'T', DTGSYL solves the transposed system Z**T*y = scale*b,
66*> which is equivalent to solve for R and L in
67*>
68*> A**T * R + D**T * L = scale * C (3)
69*> R * B**T + L * E**T = scale * -F
70*>
71*> This case (TRANS = 'T') is used to compute an one-norm-based estimate
72*> of Dif[(A,D), (B,E)], the separation between the matrix pairs (A,D)
73*> and (B,E), using DLACON.
74*>
75*> If IJOB >= 1, DTGSYL computes a Frobenius norm-based estimate
76*> of Dif[(A,D),(B,E)]. That is, the reciprocal of a lower bound on the
77*> reciprocal of the smallest singular value of Z. See [1-2] for more
78*> information.
79*>
80*> This is a level 3 BLAS algorithm.
81*> \endverbatim
82*
83* Arguments:
84* ==========
85*
86*> \param[in] TRANS
87*> \verbatim
88*> TRANS is CHARACTER*1
89*> = 'N': solve the generalized Sylvester equation (1).
90*> = 'T': solve the 'transposed' system (3).
91*> \endverbatim
92*>
93*> \param[in] IJOB
94*> \verbatim
95*> IJOB is INTEGER
96*> Specifies what kind of functionality to be performed.
97*> = 0: solve (1) only.
98*> = 1: The functionality of 0 and 3.
99*> = 2: The functionality of 0 and 4.
100*> = 3: Only an estimate of Dif[(A,D), (B,E)] is computed.
101*> (look ahead strategy IJOB = 1 is used).
102*> = 4: Only an estimate of Dif[(A,D), (B,E)] is computed.
103*> ( DGECON on sub-systems is used ).
104*> Not referenced if TRANS = 'T'.
105*> \endverbatim
106*>
107*> \param[in] M
108*> \verbatim
109*> M is INTEGER
110*> The order of the matrices A and D, and the row dimension of
111*> the matrices C, F, R and L.
112*> \endverbatim
113*>
114*> \param[in] N
115*> \verbatim
116*> N is INTEGER
117*> The order of the matrices B and E, and the column dimension
118*> of the matrices C, F, R and L.
119*> \endverbatim
120*>
121*> \param[in] A
122*> \verbatim
123*> A is DOUBLE PRECISION array, dimension (LDA, M)
124*> The upper quasi triangular matrix A.
125*> \endverbatim
126*>
127*> \param[in] LDA
128*> \verbatim
129*> LDA is INTEGER
130*> The leading dimension of the array A. LDA >= max(1, M).
131*> \endverbatim
132*>
133*> \param[in] B
134*> \verbatim
135*> B is DOUBLE PRECISION array, dimension (LDB, N)
136*> The upper quasi triangular matrix B.
137*> \endverbatim
138*>
139*> \param[in] LDB
140*> \verbatim
141*> LDB is INTEGER
142*> The leading dimension of the array B. LDB >= max(1, N).
143*> \endverbatim
144*>
145*> \param[in,out] C
146*> \verbatim
147*> C is DOUBLE PRECISION array, dimension (LDC, N)
148*> On entry, C contains the right-hand-side of the first matrix
149*> equation in (1) or (3).
150*> On exit, if IJOB = 0, 1 or 2, C has been overwritten by
151*> the solution R. If IJOB = 3 or 4 and TRANS = 'N', C holds R,
152*> the solution achieved during the computation of the
153*> Dif-estimate.
154*> \endverbatim
155*>
156*> \param[in] LDC
157*> \verbatim
158*> LDC is INTEGER
159*> The leading dimension of the array C. LDC >= max(1, M).
160*> \endverbatim
161*>
162*> \param[in] D
163*> \verbatim
164*> D is DOUBLE PRECISION array, dimension (LDD, M)
165*> The upper triangular matrix D.
166*> \endverbatim
167*>
168*> \param[in] LDD
169*> \verbatim
170*> LDD is INTEGER
171*> The leading dimension of the array D. LDD >= max(1, M).
172*> \endverbatim
173*>
174*> \param[in] E
175*> \verbatim
176*> E is DOUBLE PRECISION array, dimension (LDE, N)
177*> The upper triangular matrix E.
178*> \endverbatim
179*>
180*> \param[in] LDE
181*> \verbatim
182*> LDE is INTEGER
183*> The leading dimension of the array E. LDE >= max(1, N).
184*> \endverbatim
185*>
186*> \param[in,out] F
187*> \verbatim
188*> F is DOUBLE PRECISION array, dimension (LDF, N)
189*> On entry, F contains the right-hand-side of the second matrix
190*> equation in (1) or (3).
191*> On exit, if IJOB = 0, 1 or 2, F has been overwritten by
192*> the solution L. If IJOB = 3 or 4 and TRANS = 'N', F holds L,
193*> the solution achieved during the computation of the
194*> Dif-estimate.
195*> \endverbatim
196*>
197*> \param[in] LDF
198*> \verbatim
199*> LDF is INTEGER
200*> The leading dimension of the array F. LDF >= max(1, M).
201*> \endverbatim
202*>
203*> \param[out] DIF
204*> \verbatim
205*> DIF is DOUBLE PRECISION
206*> On exit DIF is the reciprocal of a lower bound of the
207*> reciprocal of the Dif-function, i.e. DIF is an upper bound of
208*> Dif[(A,D), (B,E)] = sigma_min(Z), where Z as in (2).
209*> IF IJOB = 0 or TRANS = 'T', DIF is not touched.
210*> \endverbatim
211*>
212*> \param[out] SCALE
213*> \verbatim
214*> SCALE is DOUBLE PRECISION
215*> On exit SCALE is the scaling factor in (1) or (3).
216*> If 0 < SCALE < 1, C and F hold the solutions R and L, resp.,
217*> to a slightly perturbed system but the input matrices A, B, D
218*> and E have not been changed. If SCALE = 0, C and F hold the
219*> solutions R and L, respectively, to the homogeneous system
220*> with C = F = 0. Normally, SCALE = 1.
221*> \endverbatim
222*>
223*> \param[out] WORK
224*> \verbatim
225*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))
226*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
227*> \endverbatim
228*>
229*> \param[in] LWORK
230*> \verbatim
231*> LWORK is INTEGER
232*> The dimension of the array WORK. LWORK > = 1.
233*> If IJOB = 1 or 2 and TRANS = 'N', LWORK >= max(1,2*M*N).
234*>
235*> If LWORK = -1, then a workspace query is assumed; the routine
236*> only calculates the optimal size of the WORK array, returns
237*> this value as the first entry of the WORK array, and no error
238*> message related to LWORK is issued by XERBLA.
239*> \endverbatim
240*>
241*> \param[out] IWORK
242*> \verbatim
243*> IWORK is INTEGER array, dimension (M+N+6)
244*> \endverbatim
245*>
246*> \param[out] INFO
247*> \verbatim
248*> INFO is INTEGER
249*> =0: successful exit
250*> <0: If INFO = -i, the i-th argument had an illegal value.
251*> >0: (A, D) and (B, E) have common or close eigenvalues.
252*> \endverbatim
253*
254* Authors:
255* ========
256*
257*> \author Univ. of Tennessee
258*> \author Univ. of California Berkeley
259*> \author Univ. of Colorado Denver
260*> \author NAG Ltd.
261*
262*> \ingroup tgsyl
263*
264*> \par Contributors:
265* ==================
266*>
267*> Bo Kagstrom and Peter Poromaa, Department of Computing Science,
268*> Umea University, S-901 87 Umea, Sweden.
269*
270*> \par References:
271* ================
272*>
273*> \verbatim
274*>
275*> [1] B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software
276*> for Solving the Generalized Sylvester Equation and Estimating the
277*> Separation between Regular Matrix Pairs, Report UMINF - 93.23,
278*> Department of Computing Science, Umea University, S-901 87 Umea,
279*> Sweden, December 1993, Revised April 1994, Also as LAPACK Working
280*> Note 75. To appear in ACM Trans. on Math. Software, Vol 22,
281*> No 1, 1996.
282*>
283*> [2] B. Kagstrom, A Perturbation Analysis of the Generalized Sylvester
284*> Equation (AR - LB, DR - LE ) = (C, F), SIAM J. Matrix Anal.
285*> Appl., 15(4):1045-1060, 1994
286*>
287*> [3] B. Kagstrom and L. Westin, Generalized Schur Methods with
288*> Condition Estimators for Solving the Generalized Sylvester
289*> Equation, IEEE Transactions on Automatic Control, Vol. 34, No. 7,
290*> July 1989, pp 745-751.
291*> \endverbatim
292*>
293* =====================================================================
294 SUBROUTINE dtgsyl( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC,
295 $ D,
296 $ LDD, E, LDE, F, LDF, SCALE, DIF, WORK, LWORK,
297 $ IWORK, INFO )
298*
299* -- LAPACK computational routine --
300* -- LAPACK is a software package provided by Univ. of Tennessee, --
301* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
302*
303* .. Scalar Arguments ..
304 CHARACTER TRANS
305 INTEGER IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF,
306 $ LWORK, M, N
307 DOUBLE PRECISION DIF, SCALE
308* ..
309* .. Array Arguments ..
310 INTEGER IWORK( * )
311 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ),
312 $ D( LDD, * ), E( LDE, * ), F( LDF, * ),
313 $ work( * )
314* ..
315*
316* =====================================================================
317* Replaced various illegal calls to DCOPY by calls to DLASET.
318* Sven Hammarling, 1/5/02.
319*
320* .. Parameters ..
321 DOUBLE PRECISION ZERO, ONE
322 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
323* ..
324* .. Local Scalars ..
325 LOGICAL LQUERY, NOTRAN
326 INTEGER I, IE, IFUNC, IROUND, IS, ISOLVE, J, JE, JS, K,
327 $ LINFO, LWMIN, MB, NB, P, PPQQ, PQ, Q
328 DOUBLE PRECISION DSCALE, DSUM, SCALE2, SCALOC
329* ..
330* .. External Functions ..
331 LOGICAL LSAME
332 INTEGER ILAENV
333 EXTERNAL LSAME, ILAENV
334* ..
335* .. External Subroutines ..
336 EXTERNAL dgemm, dlacpy, dlaset, dscal, dtgsy2,
337 $ xerbla
338* ..
339* .. Intrinsic Functions ..
340 INTRINSIC dble, max, sqrt
341* ..
342* .. Executable Statements ..
343*
344* Decode and test input parameters
345*
346 info = 0
347 notran = lsame( trans, 'N' )
348 lquery = ( lwork.EQ.-1 )
349*
350 IF( .NOT.notran .AND. .NOT.lsame( trans, 'T' ) ) THEN
351 info = -1
352 ELSE IF( notran ) THEN
353 IF( ( ijob.LT.0 ) .OR. ( ijob.GT.4 ) ) THEN
354 info = -2
355 END IF
356 END IF
357 IF( info.EQ.0 ) THEN
358 IF( m.LE.0 ) THEN
359 info = -3
360 ELSE IF( n.LE.0 ) THEN
361 info = -4
362 ELSE IF( lda.LT.max( 1, m ) ) THEN
363 info = -6
364 ELSE IF( ldb.LT.max( 1, n ) ) THEN
365 info = -8
366 ELSE IF( ldc.LT.max( 1, m ) ) THEN
367 info = -10
368 ELSE IF( ldd.LT.max( 1, m ) ) THEN
369 info = -12
370 ELSE IF( lde.LT.max( 1, n ) ) THEN
371 info = -14
372 ELSE IF( ldf.LT.max( 1, m ) ) THEN
373 info = -16
374 END IF
375 END IF
376*
377 IF( info.EQ.0 ) THEN
378 IF( notran ) THEN
379 IF( ijob.EQ.1 .OR. ijob.EQ.2 ) THEN
380 lwmin = max( 1, 2*m*n )
381 ELSE
382 lwmin = 1
383 END IF
384 ELSE
385 lwmin = 1
386 END IF
387 work( 1 ) = lwmin
388*
389 IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
390 info = -20
391 END IF
392 END IF
393*
394 IF( info.NE.0 ) THEN
395 CALL xerbla( 'DTGSYL', -info )
396 RETURN
397 ELSE IF( lquery ) THEN
398 RETURN
399 END IF
400*
401* Quick return if possible
402*
403 IF( m.EQ.0 .OR. n.EQ.0 ) THEN
404 scale = 1
405 IF( notran ) THEN
406 IF( ijob.NE.0 ) THEN
407 dif = 0
408 END IF
409 END IF
410 RETURN
411 END IF
412*
413* Determine optimal block sizes MB and NB
414*
415 mb = ilaenv( 2, 'DTGSYL', trans, m, n, -1, -1 )
416 nb = ilaenv( 5, 'DTGSYL', trans, m, n, -1, -1 )
417*
418 isolve = 1
419 ifunc = 0
420 IF( notran ) THEN
421 IF( ijob.GE.3 ) THEN
422 ifunc = ijob - 2
423 CALL dlaset( 'F', m, n, zero, zero, c, ldc )
424 CALL dlaset( 'F', m, n, zero, zero, f, ldf )
425 ELSE IF( ijob.GE.1 ) THEN
426 isolve = 2
427 END IF
428 END IF
429*
430 IF( ( mb.LE.1 .AND. nb.LE.1 ) .OR. ( mb.GE.m .AND. nb.GE.n ) )
431 $ THEN
432*
433 DO 30 iround = 1, isolve
434*
435* Use unblocked Level 2 solver
436*
437 dscale = zero
438 dsum = one
439 pq = 0
440 CALL dtgsy2( trans, ifunc, m, n, a, lda, b, ldb, c, ldc,
441 $ d,
442 $ ldd, e, lde, f, ldf, scale, dsum, dscale,
443 $ iwork, pq, info )
444 IF( dscale.NE.zero ) THEN
445 IF( ijob.EQ.1 .OR. ijob.EQ.3 ) THEN
446 dif = sqrt( dble( 2*m*n ) ) / ( dscale*sqrt( dsum ) )
447 ELSE
448 dif = sqrt( dble( pq ) ) / ( dscale*sqrt( dsum ) )
449 END IF
450 END IF
451*
452 IF( isolve.EQ.2 .AND. iround.EQ.1 ) THEN
453 IF( notran ) THEN
454 ifunc = ijob
455 END IF
456 scale2 = scale
457 CALL dlacpy( 'F', m, n, c, ldc, work, m )
458 CALL dlacpy( 'F', m, n, f, ldf, work( m*n+1 ), m )
459 CALL dlaset( 'F', m, n, zero, zero, c, ldc )
460 CALL dlaset( 'F', m, n, zero, zero, f, ldf )
461 ELSE IF( isolve.EQ.2 .AND. iround.EQ.2 ) THEN
462 CALL dlacpy( 'F', m, n, work, m, c, ldc )
463 CALL dlacpy( 'F', m, n, work( m*n+1 ), m, f, ldf )
464 scale = scale2
465 END IF
466 30 CONTINUE
467*
468 RETURN
469 END IF
470*
471* Determine block structure of A
472*
473 p = 0
474 i = 1
475 40 CONTINUE
476 IF( i.GT.m )
477 $ GO TO 50
478 p = p + 1
479 iwork( p ) = i
480 i = i + mb
481 IF( i.GE.m )
482 $ GO TO 50
483 IF( a( i, i-1 ).NE.zero )
484 $ i = i + 1
485 GO TO 40
486 50 CONTINUE
487*
488 iwork( p+1 ) = m + 1
489 IF( iwork( p ).EQ.iwork( p+1 ) )
490 $ p = p - 1
491*
492* Determine block structure of B
493*
494 q = p + 1
495 j = 1
496 60 CONTINUE
497 IF( j.GT.n )
498 $ GO TO 70
499 q = q + 1
500 iwork( q ) = j
501 j = j + nb
502 IF( j.GE.n )
503 $ GO TO 70
504 IF( b( j, j-1 ).NE.zero )
505 $ j = j + 1
506 GO TO 60
507 70 CONTINUE
508*
509 iwork( q+1 ) = n + 1
510 IF( iwork( q ).EQ.iwork( q+1 ) )
511 $ q = q - 1
512*
513 IF( notran ) THEN
514*
515 DO 150 iround = 1, isolve
516*
517* Solve (I, J)-subsystem
518* A(I, I) * R(I, J) - L(I, J) * B(J, J) = C(I, J)
519* D(I, I) * R(I, J) - L(I, J) * E(J, J) = F(I, J)
520* for I = P, P - 1,..., 1; J = 1, 2,..., Q
521*
522 dscale = zero
523 dsum = one
524 pq = 0
525 scale = one
526 DO 130 j = p + 2, q
527 js = iwork( j )
528 je = iwork( j+1 ) - 1
529 nb = je - js + 1
530 DO 120 i = p, 1, -1
531 is = iwork( i )
532 ie = iwork( i+1 ) - 1
533 mb = ie - is + 1
534 ppqq = 0
535 CALL dtgsy2( trans, ifunc, mb, nb, a( is, is ),
536 $ lda,
537 $ b( js, js ), ldb, c( is, js ), ldc,
538 $ d( is, is ), ldd, e( js, js ), lde,
539 $ f( is, js ), ldf, scaloc, dsum, dscale,
540 $ iwork( q+2 ), ppqq, linfo )
541 IF( linfo.GT.0 )
542 $ info = linfo
543*
544 pq = pq + ppqq
545 IF( scaloc.NE.one ) THEN
546 DO 80 k = 1, js - 1
547 CALL dscal( m, scaloc, c( 1, k ), 1 )
548 CALL dscal( m, scaloc, f( 1, k ), 1 )
549 80 CONTINUE
550 DO 90 k = js, je
551 CALL dscal( is-1, scaloc, c( 1, k ), 1 )
552 CALL dscal( is-1, scaloc, f( 1, k ), 1 )
553 90 CONTINUE
554 DO 100 k = js, je
555 CALL dscal( m-ie, scaloc, c( ie+1, k ), 1 )
556 CALL dscal( m-ie, scaloc, f( ie+1, k ), 1 )
557 100 CONTINUE
558 DO 110 k = je + 1, n
559 CALL dscal( m, scaloc, c( 1, k ), 1 )
560 CALL dscal( m, scaloc, f( 1, k ), 1 )
561 110 CONTINUE
562 scale = scale*scaloc
563 END IF
564*
565* Substitute R(I, J) and L(I, J) into remaining
566* equation.
567*
568 IF( i.GT.1 ) THEN
569 CALL dgemm( 'N', 'N', is-1, nb, mb, -one,
570 $ a( 1, is ), lda, c( is, js ), ldc, one,
571 $ c( 1, js ), ldc )
572 CALL dgemm( 'N', 'N', is-1, nb, mb, -one,
573 $ d( 1, is ), ldd, c( is, js ), ldc, one,
574 $ f( 1, js ), ldf )
575 END IF
576 IF( j.LT.q ) THEN
577 CALL dgemm( 'N', 'N', mb, n-je, nb, one,
578 $ f( is, js ), ldf, b( js, je+1 ), ldb,
579 $ one, c( is, je+1 ), ldc )
580 CALL dgemm( 'N', 'N', mb, n-je, nb, one,
581 $ f( is, js ), ldf, e( js, je+1 ), lde,
582 $ one, f( is, je+1 ), ldf )
583 END IF
584 120 CONTINUE
585 130 CONTINUE
586 IF( dscale.NE.zero ) THEN
587 IF( ijob.EQ.1 .OR. ijob.EQ.3 ) THEN
588 dif = sqrt( dble( 2*m*n ) ) / ( dscale*sqrt( dsum ) )
589 ELSE
590 dif = sqrt( dble( pq ) ) / ( dscale*sqrt( dsum ) )
591 END IF
592 END IF
593 IF( isolve.EQ.2 .AND. iround.EQ.1 ) THEN
594 IF( notran ) THEN
595 ifunc = ijob
596 END IF
597 scale2 = scale
598 CALL dlacpy( 'F', m, n, c, ldc, work, m )
599 CALL dlacpy( 'F', m, n, f, ldf, work( m*n+1 ), m )
600 CALL dlaset( 'F', m, n, zero, zero, c, ldc )
601 CALL dlaset( 'F', m, n, zero, zero, f, ldf )
602 ELSE IF( isolve.EQ.2 .AND. iround.EQ.2 ) THEN
603 CALL dlacpy( 'F', m, n, work, m, c, ldc )
604 CALL dlacpy( 'F', m, n, work( m*n+1 ), m, f, ldf )
605 scale = scale2
606 END IF
607 150 CONTINUE
608*
609 ELSE
610*
611* Solve transposed (I, J)-subsystem
612* A(I, I)**T * R(I, J) + D(I, I)**T * L(I, J) = C(I, J)
613* R(I, J) * B(J, J)**T + L(I, J) * E(J, J)**T = -F(I, J)
614* for I = 1,2,..., P; J = Q, Q-1,..., 1
615*
616 scale = one
617 DO 210 i = 1, p
618 is = iwork( i )
619 ie = iwork( i+1 ) - 1
620 mb = ie - is + 1
621 DO 200 j = q, p + 2, -1
622 js = iwork( j )
623 je = iwork( j+1 ) - 1
624 nb = je - js + 1
625 CALL dtgsy2( trans, ifunc, mb, nb, a( is, is ), lda,
626 $ b( js, js ), ldb, c( is, js ), ldc,
627 $ d( is, is ), ldd, e( js, js ), lde,
628 $ f( is, js ), ldf, scaloc, dsum, dscale,
629 $ iwork( q+2 ), ppqq, linfo )
630 IF( linfo.GT.0 )
631 $ info = linfo
632 IF( scaloc.NE.one ) THEN
633 DO 160 k = 1, js - 1
634 CALL dscal( m, scaloc, c( 1, k ), 1 )
635 CALL dscal( m, scaloc, f( 1, k ), 1 )
636 160 CONTINUE
637 DO 170 k = js, je
638 CALL dscal( is-1, scaloc, c( 1, k ), 1 )
639 CALL dscal( is-1, scaloc, f( 1, k ), 1 )
640 170 CONTINUE
641 DO 180 k = js, je
642 CALL dscal( m-ie, scaloc, c( ie+1, k ), 1 )
643 CALL dscal( m-ie, scaloc, f( ie+1, k ), 1 )
644 180 CONTINUE
645 DO 190 k = je + 1, n
646 CALL dscal( m, scaloc, c( 1, k ), 1 )
647 CALL dscal( m, scaloc, f( 1, k ), 1 )
648 190 CONTINUE
649 scale = scale*scaloc
650 END IF
651*
652* Substitute R(I, J) and L(I, J) into remaining equation.
653*
654 IF( j.GT.p+2 ) THEN
655 CALL dgemm( 'N', 'T', mb, js-1, nb, one, c( is,
656 $ js ),
657 $ ldc, b( 1, js ), ldb, one, f( is, 1 ),
658 $ ldf )
659 CALL dgemm( 'N', 'T', mb, js-1, nb, one, f( is,
660 $ js ),
661 $ ldf, e( 1, js ), lde, one, f( is, 1 ),
662 $ ldf )
663 END IF
664 IF( i.LT.p ) THEN
665 CALL dgemm( 'T', 'N', m-ie, nb, mb, -one,
666 $ a( is, ie+1 ), lda, c( is, js ), ldc, one,
667 $ c( ie+1, js ), ldc )
668 CALL dgemm( 'T', 'N', m-ie, nb, mb, -one,
669 $ d( is, ie+1 ), ldd, f( is, js ), ldf, one,
670 $ c( ie+1, js ), ldc )
671 END IF
672 200 CONTINUE
673 210 CONTINUE
674*
675 END IF
676*
677 work( 1 ) = lwmin
678*
679 RETURN
680*
681* End of DTGSYL
682*
683 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
Definition dgemm.f:188
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
Definition dlacpy.f:101
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition dlaset.f:108
subroutine dscal(n, da, dx, incx)
DSCAL
Definition dscal.f:79
subroutine dtgsy2(trans, ijob, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, rdsum, rdscal, iwork, pq, info)
DTGSY2 solves the generalized Sylvester equation (unblocked algorithm).
Definition dtgsy2.f:273
subroutine dtgsyl(trans, ijob, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, dif, work, lwork, iwork, info)
DTGSYL
Definition dtgsyl.f:298