3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download CTGSYL + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ctgsyl.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ctgsyl.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ctgsyl.f">
21 * SUBROUTINE CTGSYL( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D,
22 * LDD, E, LDE, F, LDF, SCALE, DIF, WORK, LWORK,
25 * .. Scalar Arguments ..
27 * INTEGER IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF,
31 * .. Array Arguments ..
33 * COMPLEX A( LDA, * ), B( LDB, * ), C( LDC, * ),
34 * $ D( LDD, * ), E( LDE, * ), F( LDF, * ),
44 *> CTGSYL solves the generalized Sylvester equation:
46 *> A * R - L * B = scale * C (1)
47 *> D * R - L * E = scale * F
49 *> where R and L are unknown m-by-n matrices, (A, D), (B, E) and
50 *> (C, F) are given matrix pairs of size m-by-m, n-by-n and m-by-n,
51 *> respectively, with complex entries. A, B, D and E are upper
52 *> triangular (i.e., (A,D) and (B,E) in generalized Schur form).
54 *> The solution (R, L) overwrites (C, F). 0 <= SCALE <= 1
55 *> is an output scaling factor chosen to avoid overflow.
57 *> In matrix notation (1) is equivalent to solve Zx = scale*b, where Z
60 *> Z = [ kron(In, A) -kron(B**H, Im) ] (2)
61 *> [ kron(In, D) -kron(E**H, Im) ],
63 *> Here Ix is the identity matrix of size x and X**H is the conjugate
64 *> transpose of X. Kron(X, Y) is the Kronecker product between the
67 *> If TRANS = 'C', y in the conjugate transposed system Z**H *y = scale*b
68 *> is solved for, which is equivalent to solve for R and L in
70 *> A**H * R + D**H * L = scale * C (3)
71 *> R * B**H + L * E**H = scale * -F
73 *> This case (TRANS = 'C') is used to compute an one-norm-based estimate
74 *> of Dif[(A,D), (B,E)], the separation between the matrix pairs (A,D)
75 *> and (B,E), using CLACON.
77 *> If IJOB >= 1, CTGSYL computes a Frobenius norm-based estimate of
78 *> Dif[(A,D),(B,E)]. That is, the reciprocal of a lower bound on the
79 *> reciprocal of the smallest singular value of Z.
81 *> This is a level-3 BLAS algorithm.
89 *> TRANS is CHARACTER*1
90 *> = 'N': solve the generalized sylvester equation (1).
91 *> = 'C': solve the "conjugate transposed" system (3).
97 *> Specifies what kind of functionality to be performed.
98 *> =0: solve (1) only.
99 *> =1: The functionality of 0 and 3.
100 *> =2: The functionality of 0 and 4.
101 *> =3: Only an estimate of Dif[(A,D), (B,E)] is computed.
102 *> (look ahead strategy is used).
103 *> =4: Only an estimate of Dif[(A,D), (B,E)] is computed.
104 *> (CGECON on sub-systems is used).
105 *> Not referenced if TRANS = 'C'.
111 *> The order of the matrices A and D, and the row dimension of
112 *> the matrices C, F, R and L.
118 *> The order of the matrices B and E, and the column dimension
119 *> of the matrices C, F, R and L.
124 *> A is COMPLEX array, dimension (LDA, M)
125 *> The upper triangular matrix A.
131 *> The leading dimension of the array A. LDA >= max(1, M).
136 *> B is COMPLEX array, dimension (LDB, N)
137 *> The upper triangular matrix B.
143 *> The leading dimension of the array B. LDB >= max(1, N).
148 *> C is COMPLEX array, dimension (LDC, N)
149 *> On entry, C contains the right-hand-side of the first matrix
150 *> equation in (1) or (3).
151 *> On exit, if IJOB = 0, 1 or 2, C has been overwritten by
152 *> the solution R. If IJOB = 3 or 4 and TRANS = 'N', C holds R,
153 *> the solution achieved during the computation of the
160 *> The leading dimension of the array C. LDC >= max(1, M).
165 *> D is COMPLEX array, dimension (LDD, M)
166 *> The upper triangular matrix D.
172 *> The leading dimension of the array D. LDD >= max(1, M).
177 *> E is COMPLEX array, dimension (LDE, N)
178 *> The upper triangular matrix E.
184 *> The leading dimension of the array E. LDE >= max(1, N).
189 *> F is COMPLEX array, dimension (LDF, N)
190 *> On entry, F contains the right-hand-side of the second matrix
191 *> equation in (1) or (3).
192 *> On exit, if IJOB = 0, 1 or 2, F has been overwritten by
193 *> the solution L. If IJOB = 3 or 4 and TRANS = 'N', F holds L,
194 *> the solution achieved during the computation of the
201 *> The leading dimension of the array F. LDF >= max(1, M).
207 *> On exit DIF is the reciprocal of a lower bound of the
208 *> reciprocal of the Dif-function, i.e. DIF is an upper bound of
209 *> Dif[(A,D), (B,E)] = sigma-min(Z), where Z as in (2).
210 *> IF IJOB = 0 or TRANS = 'C', DIF is not referenced.
216 *> On exit SCALE is the scaling factor in (1) or (3).
217 *> If 0 < SCALE < 1, C and F hold the solutions R and L, resp.,
218 *> to a slightly perturbed system but the input matrices A, B,
219 *> D and E have not been changed. If SCALE = 0, R and L will
220 *> hold the solutions to the homogenious system with C = F = 0.
225 *> WORK is COMPLEX array, dimension (MAX(1,LWORK))
226 *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
232 *> The dimension of the array WORK. LWORK > = 1.
233 *> If IJOB = 1 or 2 and TRANS = 'N', LWORK >= max(1,2*M*N).
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.
243 *> IWORK is INTEGER array, dimension (M+N+2)
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 very close
258 *> \author Univ. of Tennessee
259 *> \author Univ. of California Berkeley
260 *> \author Univ. of Colorado Denver
263 *> \date November 2011
265 *> \ingroup complexSYcomputational
267 *> \par Contributors:
270 *> Bo Kagstrom and Peter Poromaa, Department of Computing Science,
271 *> Umea University, S-901 87 Umea, Sweden.
276 *> [1] B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software
277 *> for Solving the Generalized Sylvester Equation and Estimating the
278 *> Separation between Regular Matrix Pairs, Report UMINF - 93.23,
279 *> Department of Computing Science, Umea University, S-901 87 Umea,
280 *> Sweden, December 1993, Revised April 1994, Also as LAPACK Working
281 *> Note 75. To appear in ACM Trans. on Math. Software, Vol 22,
284 *> [2] B. Kagstrom, A Perturbation Analysis of the Generalized Sylvester
285 *> Equation (AR - LB, DR - LE ) = (C, F), SIAM J. Matrix Anal.
286 *> Appl., 15(4):1045-1060, 1994.
288 *> [3] B. Kagstrom and L. Westin, Generalized Schur Methods with
289 *> Condition Estimators for Solving the Generalized Sylvester
290 *> Equation, IEEE Transactions on Automatic Control, Vol. 34, No. 7,
291 *> July 1989, pp 745-751.
293 * =====================================================================
294 SUBROUTINE CTGSYL( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D,
295 $ LDD, E, LDE, F, LDF, SCALE, DIF, WORK, LWORK,
298 * -- LAPACK computational routine (version 3.4.0) --
299 * -- LAPACK is a software package provided by Univ. of Tennessee, --
300 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
303 * .. Scalar Arguments ..
305 INTEGER IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF,
309 * .. Array Arguments ..
311 COMPLEX A( LDA, * ), B( LDB, * ), C( LDC, * ),
312 $ D( LDD, * ), E( LDE, * ), F( LDF, * ),
316 * =====================================================================
317 * Replaced various illegal calls to CCOPY by calls to CLASET.
318 * Sven Hammarling, 1/5/02.
322 PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 )
324 PARAMETER ( CZERO = (0.0E+0, 0.0E+0) )
326 * .. Local Scalars ..
327 LOGICAL LQUERY, NOTRAN
328 INTEGER I, IE, IFUNC, IROUND, IS, ISOLVE, J, JE, JS, K,
329 $ LINFO, LWMIN, MB, NB, P, PQ, Q
330 REAL DSCALE, DSUM, SCALE2, SCALOC
332 * .. External Functions ..
335 EXTERNAL LSAME, ILAENV
337 * .. External Subroutines ..
338 EXTERNAL CGEMM, CLACPY, CLASET, CSCAL, CTGSY2, XERBLA
340 * .. Intrinsic Functions ..
341 INTRINSIC CMPLX, MAX, REAL, SQRT
343 * .. Executable Statements ..
345 * Decode and test input parameters
348 NOTRAN = LSAME( TRANS, 'N' )
349 LQUERY = ( LWORK.EQ.-1 )
351 IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
353 ELSE IF( NOTRAN ) THEN
354 IF( ( IJOB.LT.0 ) .OR. ( IJOB.GT.4 ) ) THEN
361 ELSE IF( N.LE.0 ) THEN
363 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
365 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
367 ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
369 ELSE IF( LDD.LT.MAX( 1, M ) ) THEN
371 ELSE IF( LDE.LT.MAX( 1, N ) ) THEN
373 ELSE IF( LDF.LT.MAX( 1, M ) ) THEN
380 IF( IJOB.EQ.1 .OR. IJOB.EQ.2 ) THEN
381 LWMIN = MAX( 1, 2*M*N )
390 IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
396 CALL XERBLA( 'CTGSYL', -INFO )
398 ELSE IF( LQUERY ) THEN
402 * Quick return if possible
404 IF( M.EQ.0 .OR. N.EQ.0 ) THEN
414 * Determine optimal block sizes MB and NB
416 MB = ILAENV( 2, 'CTGSYL', TRANS, M, N, -1, -1 )
417 NB = ILAENV( 5, 'CTGSYL', TRANS, M, N, -1, -1 )
424 CALL CLASET( 'F', M, N, CZERO, CZERO, C, LDC )
425 CALL CLASET( 'F', M, N, CZERO, CZERO, F, LDF )
426 ELSE IF( IJOB.GE.1 .AND. NOTRAN ) THEN
431 IF( ( MB.LE.1 .AND. NB.LE.1 ) .OR. ( MB.GE.M .AND. NB.GE.N ) )
434 * Use unblocked Level 2 solver
436 DO 30 IROUND = 1, ISOLVE
442 CALL CTGSY2( TRANS, IFUNC, M, N, A, LDA, B, LDB, C, LDC, D,
443 $ LDD, E, LDE, F, LDF, SCALE, DSUM, DSCALE,
445 IF( DSCALE.NE.ZERO ) THEN
446 IF( IJOB.EQ.1 .OR. IJOB.EQ.3 ) THEN
447 DIF = SQRT( REAL( 2*M*N ) ) / ( DSCALE*SQRT( DSUM ) )
449 DIF = SQRT( REAL( PQ ) ) / ( DSCALE*SQRT( DSUM ) )
452 IF( ISOLVE.EQ.2 .AND. IROUND.EQ.1 ) THEN
457 CALL CLACPY( 'F', M, N, C, LDC, WORK, M )
458 CALL CLACPY( 'F', M, N, F, LDF, WORK( M*N+1 ), M )
459 CALL CLASET( 'F', M, N, CZERO, CZERO, C, LDC )
460 CALL CLASET( 'F', M, N, CZERO, CZERO, F, LDF )
461 ELSE IF( ISOLVE.EQ.2 .AND. IROUND.EQ.2 ) THEN
462 CALL CLACPY( 'F', M, N, WORK, M, C, LDC )
463 CALL CLACPY( 'F', M, N, WORK( M*N+1 ), M, F, LDF )
472 * Determine block structure of A
487 IF( IWORK( P ).EQ.IWORK( P+1 ) )
490 * Determine block structure of B
507 IF( IWORK( Q ).EQ.IWORK( Q+1 ) )
511 DO 150 IROUND = 1, ISOLVE
513 * Solve (I, J) - subsystem
514 * A(I, I) * R(I, J) - L(I, J) * B(J, J) = C(I, J)
515 * D(I, I) * R(I, J) - L(I, J) * E(J, J) = F(I, J)
516 * for I = P, P - 1, ..., 1; J = 1, 2, ..., Q
524 JE = IWORK( J+1 ) - 1
528 IE = IWORK( I+1 ) - 1
530 CALL CTGSY2( TRANS, IFUNC, MB, NB, A( IS, IS ), LDA,
531 $ B( JS, JS ), LDB, C( IS, JS ), LDC,
532 $ D( IS, IS ), LDD, E( JS, JS ), LDE,
533 $ F( IS, JS ), LDF, SCALOC, DSUM, DSCALE,
538 IF( SCALOC.NE.ONE ) THEN
540 CALL CSCAL( M, CMPLX( SCALOC, ZERO ), C( 1, K ),
542 CALL CSCAL( M, CMPLX( SCALOC, ZERO ), F( 1, K ),
546 CALL CSCAL( IS-1, CMPLX( SCALOC, ZERO ),
548 CALL CSCAL( IS-1, CMPLX( SCALOC, ZERO ),
552 CALL CSCAL( M-IE, CMPLX( SCALOC, ZERO ),
554 CALL CSCAL( M-IE, CMPLX( SCALOC, ZERO ),
558 CALL CSCAL( M, CMPLX( SCALOC, ZERO ), C( 1, K ),
560 CALL CSCAL( M, CMPLX( SCALOC, ZERO ), F( 1, K ),
566 * Substitute R(I,J) and L(I,J) into remaining equation.
569 CALL CGEMM( 'N', 'N', IS-1, NB, MB,
570 $ CMPLX( -ONE, ZERO ), A( 1, IS ), LDA,
571 $ C( IS, JS ), LDC, CMPLX( ONE, ZERO ),
573 CALL CGEMM( 'N', 'N', IS-1, NB, MB,
574 $ CMPLX( -ONE, ZERO ), D( 1, IS ), LDD,
575 $ C( IS, JS ), LDC, CMPLX( ONE, ZERO ),
579 CALL CGEMM( 'N', 'N', MB, N-JE, NB,
580 $ CMPLX( ONE, ZERO ), F( IS, JS ), LDF,
581 $ B( JS, JE+1 ), LDB, CMPLX( ONE, ZERO ),
582 $ C( IS, JE+1 ), LDC )
583 CALL CGEMM( 'N', 'N', MB, N-JE, NB,
584 $ CMPLX( ONE, ZERO ), F( IS, JS ), LDF,
585 $ E( JS, JE+1 ), LDE, CMPLX( ONE, ZERO ),
586 $ F( IS, JE+1 ), LDF )
590 IF( DSCALE.NE.ZERO ) THEN
591 IF( IJOB.EQ.1 .OR. IJOB.EQ.3 ) THEN
592 DIF = SQRT( REAL( 2*M*N ) ) / ( DSCALE*SQRT( DSUM ) )
594 DIF = SQRT( REAL( PQ ) ) / ( DSCALE*SQRT( DSUM ) )
597 IF( ISOLVE.EQ.2 .AND. IROUND.EQ.1 ) THEN
602 CALL CLACPY( 'F', M, N, C, LDC, WORK, M )
603 CALL CLACPY( 'F', M, N, F, LDF, WORK( M*N+1 ), M )
604 CALL CLASET( 'F', M, N, CZERO, CZERO, C, LDC )
605 CALL CLASET( 'F', M, N, CZERO, CZERO, F, LDF )
606 ELSE IF( ISOLVE.EQ.2 .AND. IROUND.EQ.2 ) THEN
607 CALL CLACPY( 'F', M, N, WORK, M, C, LDC )
608 CALL CLACPY( 'F', M, N, WORK( M*N+1 ), M, F, LDF )
614 * Solve transposed (I, J)-subsystem
615 * A(I, I)**H * R(I, J) + D(I, I)**H * L(I, J) = C(I, J)
616 * R(I, J) * B(J, J) + L(I, J) * E(J, J) = -F(I, J)
617 * for I = 1,2,..., P; J = Q, Q-1,..., 1
622 IE = IWORK( I+1 ) - 1
624 DO 200 J = Q, P + 2, -1
626 JE = IWORK( J+1 ) - 1
628 CALL CTGSY2( TRANS, IFUNC, MB, NB, A( IS, IS ), LDA,
629 $ B( JS, JS ), LDB, C( IS, JS ), LDC,
630 $ D( IS, IS ), LDD, E( JS, JS ), LDE,
631 $ F( IS, JS ), LDF, SCALOC, DSUM, DSCALE,
635 IF( SCALOC.NE.ONE ) THEN
637 CALL CSCAL( M, CMPLX( SCALOC, ZERO ), C( 1, K ),
639 CALL CSCAL( M, CMPLX( SCALOC, ZERO ), F( 1, K ),
643 CALL CSCAL( IS-1, CMPLX( SCALOC, ZERO ), C( 1, K ),
645 CALL CSCAL( IS-1, CMPLX( SCALOC, ZERO ), F( 1, K ),
649 CALL CSCAL( M-IE, CMPLX( SCALOC, ZERO ),
651 CALL CSCAL( M-IE, CMPLX( SCALOC, ZERO ),
655 CALL CSCAL( M, CMPLX( SCALOC, ZERO ), C( 1, K ),
657 CALL CSCAL( M, CMPLX( SCALOC, ZERO ), F( 1, K ),
663 * Substitute R(I,J) and L(I,J) into remaining equation.
666 CALL CGEMM( 'N', 'C', MB, JS-1, NB,
667 $ CMPLX( ONE, ZERO ), C( IS, JS ), LDC,
668 $ B( 1, JS ), LDB, CMPLX( ONE, ZERO ),
670 CALL CGEMM( 'N', 'C', MB, JS-1, NB,
671 $ CMPLX( ONE, ZERO ), F( IS, JS ), LDF,
672 $ E( 1, JS ), LDE, CMPLX( ONE, ZERO ),
676 CALL CGEMM( 'C', 'N', M-IE, NB, MB,
677 $ CMPLX( -ONE, ZERO ), A( IS, IE+1 ), LDA,
678 $ C( IS, JS ), LDC, CMPLX( ONE, ZERO ),
679 $ C( IE+1, JS ), LDC )
680 CALL CGEMM( 'C', 'N', M-IE, NB, MB,
681 $ CMPLX( -ONE, ZERO ), D( IS, IE+1 ), LDD,
682 $ F( IS, JS ), LDF, CMPLX( ONE, ZERO ),
683 $ C( IE+1, JS ), LDC )