Annotation of rpl/lapack/lapack/ztgsy2.f, revision 1.18
1.12 bertrand 1: *> \brief \b ZTGSY2 solves the generalized Sylvester equation (unblocked algorithm).
1.9 bertrand 2: *
3: * =========== DOCUMENTATION ===========
4: *
1.17 bertrand 5: * Online html documentation available at
6: * http://www.netlib.org/lapack/explore-html/
1.9 bertrand 7: *
8: *> \htmlonly
1.17 bertrand 9: *> Download ZTGSY2 + dependencies
10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ztgsy2.f">
11: *> [TGZ]</a>
12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ztgsy2.f">
13: *> [ZIP]</a>
14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ztgsy2.f">
1.9 bertrand 15: *> [TXT]</a>
1.17 bertrand 16: *> \endhtmlonly
1.9 bertrand 17: *
18: * Definition:
19: * ===========
20: *
21: * SUBROUTINE ZTGSY2( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D,
22: * LDD, E, LDE, F, LDF, SCALE, RDSUM, RDSCAL,
23: * INFO )
1.17 bertrand 24: *
1.9 bertrand 25: * .. Scalar Arguments ..
26: * CHARACTER TRANS
27: * INTEGER IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF, M, N
28: * DOUBLE PRECISION RDSCAL, RDSUM, SCALE
29: * ..
30: * .. Array Arguments ..
31: * COMPLEX*16 A( LDA, * ), B( LDB, * ), C( LDC, * ),
32: * $ D( LDD, * ), E( LDE, * ), F( LDF, * )
33: * ..
1.17 bertrand 34: *
1.9 bertrand 35: *
36: *> \par Purpose:
37: * =============
38: *>
39: *> \verbatim
40: *>
41: *> ZTGSY2 solves the generalized Sylvester equation
42: *>
43: *> A * R - L * B = scale * C (1)
44: *> D * R - L * E = scale * F
45: *>
46: *> using Level 1 and 2 BLAS, where R and L are unknown M-by-N matrices,
47: *> (A, D), (B, E) and (C, F) are given matrix pairs of size M-by-M,
48: *> N-by-N and M-by-N, respectively. A, B, D and E are upper triangular
49: *> (i.e., (A,D) and (B,E) in generalized Schur form).
50: *>
51: *> The solution (R, L) overwrites (C, F). 0 <= SCALE <= 1 is an output
52: *> scaling factor chosen to avoid overflow.
53: *>
54: *> In matrix notation solving equation (1) corresponds to solve
55: *> Zx = scale * b, where Z is defined as
56: *>
57: *> Z = [ kron(In, A) -kron(B**H, Im) ] (2)
58: *> [ kron(In, D) -kron(E**H, Im) ],
59: *>
60: *> Ik is the identity matrix of size k and X**H is the conjuguate transpose of X.
61: *> kron(X, Y) is the Kronecker product between the matrices X and Y.
62: *>
63: *> If TRANS = 'C', y in the conjugate transposed system Z**H*y = scale*b
64: *> is solved for, which is equivalent to solve for R and L in
65: *>
66: *> A**H * R + D**H * L = scale * C (3)
67: *> R * B**H + L * E**H = scale * -F
68: *>
69: *> This case is used to compute an estimate of Dif[(A, D), (B, E)] =
70: *> = sigma_min(Z) using reverse communicaton with ZLACON.
71: *>
72: *> ZTGSY2 also (IJOB >= 1) contributes to the computation in ZTGSYL
73: *> of an upper bound on the separation between to matrix pairs. Then
74: *> the input (A, D), (B, E) are sub-pencils of two matrix pairs in
75: *> ZTGSYL.
76: *> \endverbatim
77: *
78: * Arguments:
79: * ==========
80: *
81: *> \param[in] TRANS
82: *> \verbatim
83: *> TRANS is CHARACTER*1
84: *> = 'N', solve the generalized Sylvester equation (1).
85: *> = 'T': solve the 'transposed' system (3).
86: *> \endverbatim
87: *>
88: *> \param[in] IJOB
89: *> \verbatim
90: *> IJOB is INTEGER
91: *> Specifies what kind of functionality to be performed.
92: *> =0: solve (1) only.
93: *> =1: A contribution from this subsystem to a Frobenius
94: *> norm-based estimate of the separation between two matrix
95: *> pairs is computed. (look ahead strategy is used).
96: *> =2: A contribution from this subsystem to a Frobenius
97: *> norm-based estimate of the separation between two matrix
98: *> pairs is computed. (DGECON on sub-systems is used.)
99: *> Not referenced if TRANS = 'T'.
100: *> \endverbatim
101: *>
102: *> \param[in] M
103: *> \verbatim
104: *> M is INTEGER
105: *> On entry, M specifies the order of A and D, and the row
106: *> dimension of C, F, R and L.
107: *> \endverbatim
108: *>
109: *> \param[in] N
110: *> \verbatim
111: *> N is INTEGER
112: *> On entry, N specifies the order of B and E, and the column
113: *> dimension of C, F, R and L.
114: *> \endverbatim
115: *>
116: *> \param[in] A
117: *> \verbatim
118: *> A is COMPLEX*16 array, dimension (LDA, M)
119: *> On entry, A contains an upper triangular matrix.
120: *> \endverbatim
121: *>
122: *> \param[in] LDA
123: *> \verbatim
124: *> LDA is INTEGER
125: *> The leading dimension of the matrix A. LDA >= max(1, M).
126: *> \endverbatim
127: *>
128: *> \param[in] B
129: *> \verbatim
130: *> B is COMPLEX*16 array, dimension (LDB, N)
131: *> On entry, B contains an upper triangular matrix.
132: *> \endverbatim
133: *>
134: *> \param[in] LDB
135: *> \verbatim
136: *> LDB is INTEGER
137: *> The leading dimension of the matrix B. LDB >= max(1, N).
138: *> \endverbatim
139: *>
140: *> \param[in,out] C
141: *> \verbatim
142: *> C is COMPLEX*16 array, dimension (LDC, N)
143: *> On entry, C contains the right-hand-side of the first matrix
144: *> equation in (1).
145: *> On exit, if IJOB = 0, C has been overwritten by the solution
146: *> R.
147: *> \endverbatim
148: *>
149: *> \param[in] LDC
150: *> \verbatim
151: *> LDC is INTEGER
152: *> The leading dimension of the matrix C. LDC >= max(1, M).
153: *> \endverbatim
154: *>
155: *> \param[in] D
156: *> \verbatim
157: *> D is COMPLEX*16 array, dimension (LDD, M)
158: *> On entry, D contains an upper triangular matrix.
159: *> \endverbatim
160: *>
161: *> \param[in] LDD
162: *> \verbatim
163: *> LDD is INTEGER
164: *> The leading dimension of the matrix D. LDD >= max(1, M).
165: *> \endverbatim
166: *>
167: *> \param[in] E
168: *> \verbatim
169: *> E is COMPLEX*16 array, dimension (LDE, N)
170: *> On entry, E contains an upper triangular matrix.
171: *> \endverbatim
172: *>
173: *> \param[in] LDE
174: *> \verbatim
175: *> LDE is INTEGER
176: *> The leading dimension of the matrix E. LDE >= max(1, N).
177: *> \endverbatim
178: *>
179: *> \param[in,out] F
180: *> \verbatim
181: *> F is COMPLEX*16 array, dimension (LDF, N)
182: *> On entry, F contains the right-hand-side of the second matrix
183: *> equation in (1).
184: *> On exit, if IJOB = 0, F has been overwritten by the solution
185: *> L.
186: *> \endverbatim
187: *>
188: *> \param[in] LDF
189: *> \verbatim
190: *> LDF is INTEGER
191: *> The leading dimension of the matrix F. LDF >= max(1, M).
192: *> \endverbatim
193: *>
194: *> \param[out] SCALE
195: *> \verbatim
196: *> SCALE is DOUBLE PRECISION
197: *> On exit, 0 <= SCALE <= 1. If 0 < SCALE < 1, the solutions
198: *> R and L (C and F on entry) will hold the solutions to a
199: *> slightly perturbed system but the input matrices A, B, D and
200: *> E have not been changed. If SCALE = 0, R and L will hold the
201: *> solutions to the homogeneous system with C = F = 0.
202: *> Normally, SCALE = 1.
203: *> \endverbatim
204: *>
205: *> \param[in,out] RDSUM
206: *> \verbatim
207: *> RDSUM is DOUBLE PRECISION
208: *> On entry, the sum of squares of computed contributions to
209: *> the Dif-estimate under computation by ZTGSYL, where the
210: *> scaling factor RDSCAL (see below) has been factored out.
211: *> On exit, the corresponding sum of squares updated with the
212: *> contributions from the current sub-system.
213: *> If TRANS = 'T' RDSUM is not touched.
214: *> NOTE: RDSUM only makes sense when ZTGSY2 is called by
215: *> ZTGSYL.
216: *> \endverbatim
217: *>
218: *> \param[in,out] RDSCAL
219: *> \verbatim
220: *> RDSCAL is DOUBLE PRECISION
221: *> On entry, scaling factor used to prevent overflow in RDSUM.
222: *> On exit, RDSCAL is updated w.r.t. the current contributions
223: *> in RDSUM.
224: *> If TRANS = 'T', RDSCAL is not touched.
225: *> NOTE: RDSCAL only makes sense when ZTGSY2 is called by
226: *> ZTGSYL.
227: *> \endverbatim
228: *>
229: *> \param[out] INFO
230: *> \verbatim
231: *> INFO is INTEGER
232: *> On exit, if INFO is set to
233: *> =0: Successful exit
234: *> <0: If INFO = -i, input argument number i is illegal.
235: *> >0: The matrix pairs (A, D) and (B, E) have common or very
236: *> close eigenvalues.
237: *> \endverbatim
238: *
239: * Authors:
240: * ========
241: *
1.17 bertrand 242: *> \author Univ. of Tennessee
243: *> \author Univ. of California Berkeley
244: *> \author Univ. of Colorado Denver
245: *> \author NAG Ltd.
1.9 bertrand 246: *
1.17 bertrand 247: *> \date December 2016
1.9 bertrand 248: *
249: *> \ingroup complex16SYauxiliary
250: *
251: *> \par Contributors:
252: * ==================
253: *>
254: *> Bo Kagstrom and Peter Poromaa, Department of Computing Science,
255: *> Umea University, S-901 87 Umea, Sweden.
256: *
257: * =====================================================================
1.1 bertrand 258: SUBROUTINE ZTGSY2( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D,
259: $ LDD, E, LDE, F, LDF, SCALE, RDSUM, RDSCAL,
260: $ INFO )
261: *
1.17 bertrand 262: * -- LAPACK auxiliary routine (version 3.7.0) --
1.1 bertrand 263: * -- LAPACK is a software package provided by Univ. of Tennessee, --
264: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
1.17 bertrand 265: * December 2016
1.1 bertrand 266: *
267: * .. Scalar Arguments ..
268: CHARACTER TRANS
269: INTEGER IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF, M, N
270: DOUBLE PRECISION RDSCAL, RDSUM, SCALE
271: * ..
272: * .. Array Arguments ..
273: COMPLEX*16 A( LDA, * ), B( LDB, * ), C( LDC, * ),
274: $ D( LDD, * ), E( LDE, * ), F( LDF, * )
275: * ..
276: *
277: * =====================================================================
278: *
279: * .. Parameters ..
280: DOUBLE PRECISION ZERO, ONE
281: INTEGER LDZ
282: PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, LDZ = 2 )
283: * ..
284: * .. Local Scalars ..
285: LOGICAL NOTRAN
286: INTEGER I, IERR, J, K
287: DOUBLE PRECISION SCALOC
288: COMPLEX*16 ALPHA
289: * ..
290: * .. Local Arrays ..
291: INTEGER IPIV( LDZ ), JPIV( LDZ )
292: COMPLEX*16 RHS( LDZ ), Z( LDZ, LDZ )
293: * ..
294: * .. External Functions ..
295: LOGICAL LSAME
296: EXTERNAL LSAME
297: * ..
298: * .. External Subroutines ..
299: EXTERNAL XERBLA, ZAXPY, ZGESC2, ZGETC2, ZLATDF, ZSCAL
300: * ..
301: * .. Intrinsic Functions ..
302: INTRINSIC DCMPLX, DCONJG, MAX
303: * ..
304: * .. Executable Statements ..
305: *
306: * Decode and test input parameters
307: *
308: INFO = 0
309: IERR = 0
310: NOTRAN = LSAME( TRANS, 'N' )
311: IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
312: INFO = -1
313: ELSE IF( NOTRAN ) THEN
314: IF( ( IJOB.LT.0 ) .OR. ( IJOB.GT.2 ) ) THEN
315: INFO = -2
316: END IF
317: END IF
318: IF( INFO.EQ.0 ) THEN
319: IF( M.LE.0 ) THEN
320: INFO = -3
321: ELSE IF( N.LE.0 ) THEN
322: INFO = -4
323: ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
1.15 bertrand 324: INFO = -6
1.1 bertrand 325: ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
326: INFO = -8
327: ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
328: INFO = -10
329: ELSE IF( LDD.LT.MAX( 1, M ) ) THEN
330: INFO = -12
331: ELSE IF( LDE.LT.MAX( 1, N ) ) THEN
332: INFO = -14
333: ELSE IF( LDF.LT.MAX( 1, M ) ) THEN
334: INFO = -16
335: END IF
336: END IF
337: IF( INFO.NE.0 ) THEN
338: CALL XERBLA( 'ZTGSY2', -INFO )
339: RETURN
340: END IF
341: *
342: IF( NOTRAN ) THEN
343: *
344: * Solve (I, J) - system
345: * A(I, I) * R(I, J) - L(I, J) * B(J, J) = C(I, J)
346: * D(I, I) * R(I, J) - L(I, J) * E(J, J) = F(I, J)
347: * for I = M, M - 1, ..., 1; J = 1, 2, ..., N
348: *
349: SCALE = ONE
350: SCALOC = ONE
351: DO 30 J = 1, N
352: DO 20 I = M, 1, -1
353: *
354: * Build 2 by 2 system
355: *
356: Z( 1, 1 ) = A( I, I )
357: Z( 2, 1 ) = D( I, I )
358: Z( 1, 2 ) = -B( J, J )
359: Z( 2, 2 ) = -E( J, J )
360: *
361: * Set up right hand side(s)
362: *
363: RHS( 1 ) = C( I, J )
364: RHS( 2 ) = F( I, J )
365: *
366: * Solve Z * x = RHS
367: *
368: CALL ZGETC2( LDZ, Z, LDZ, IPIV, JPIV, IERR )
369: IF( IERR.GT.0 )
370: $ INFO = IERR
371: IF( IJOB.EQ.0 ) THEN
372: CALL ZGESC2( LDZ, Z, LDZ, RHS, IPIV, JPIV, SCALOC )
373: IF( SCALOC.NE.ONE ) THEN
374: DO 10 K = 1, N
375: CALL ZSCAL( M, DCMPLX( SCALOC, ZERO ),
376: $ C( 1, K ), 1 )
377: CALL ZSCAL( M, DCMPLX( SCALOC, ZERO ),
378: $ F( 1, K ), 1 )
379: 10 CONTINUE
380: SCALE = SCALE*SCALOC
381: END IF
382: ELSE
383: CALL ZLATDF( IJOB, LDZ, Z, LDZ, RHS, RDSUM, RDSCAL,
384: $ IPIV, JPIV )
385: END IF
386: *
387: * Unpack solution vector(s)
388: *
389: C( I, J ) = RHS( 1 )
390: F( I, J ) = RHS( 2 )
391: *
392: * Substitute R(I, J) and L(I, J) into remaining equation.
393: *
394: IF( I.GT.1 ) THEN
395: ALPHA = -RHS( 1 )
396: CALL ZAXPY( I-1, ALPHA, A( 1, I ), 1, C( 1, J ), 1 )
397: CALL ZAXPY( I-1, ALPHA, D( 1, I ), 1, F( 1, J ), 1 )
398: END IF
399: IF( J.LT.N ) THEN
400: CALL ZAXPY( N-J, RHS( 2 ), B( J, J+1 ), LDB,
401: $ C( I, J+1 ), LDC )
402: CALL ZAXPY( N-J, RHS( 2 ), E( J, J+1 ), LDE,
403: $ F( I, J+1 ), LDF )
404: END IF
405: *
406: 20 CONTINUE
407: 30 CONTINUE
408: ELSE
409: *
410: * Solve transposed (I, J) - system:
1.8 bertrand 411: * A(I, I)**H * R(I, J) + D(I, I)**H * L(J, J) = C(I, J)
1.1 bertrand 412: * R(I, I) * B(J, J) + L(I, J) * E(J, J) = -F(I, J)
413: * for I = 1, 2, ..., M, J = N, N - 1, ..., 1
414: *
415: SCALE = ONE
416: SCALOC = ONE
417: DO 80 I = 1, M
418: DO 70 J = N, 1, -1
419: *
1.8 bertrand 420: * Build 2 by 2 system Z**H
1.1 bertrand 421: *
422: Z( 1, 1 ) = DCONJG( A( I, I ) )
423: Z( 2, 1 ) = -DCONJG( B( J, J ) )
424: Z( 1, 2 ) = DCONJG( D( I, I ) )
425: Z( 2, 2 ) = -DCONJG( E( J, J ) )
426: *
427: *
428: * Set up right hand side(s)
429: *
430: RHS( 1 ) = C( I, J )
431: RHS( 2 ) = F( I, J )
432: *
1.8 bertrand 433: * Solve Z**H * x = RHS
1.1 bertrand 434: *
435: CALL ZGETC2( LDZ, Z, LDZ, IPIV, JPIV, IERR )
436: IF( IERR.GT.0 )
437: $ INFO = IERR
438: CALL ZGESC2( LDZ, Z, LDZ, RHS, IPIV, JPIV, SCALOC )
439: IF( SCALOC.NE.ONE ) THEN
440: DO 40 K = 1, N
441: CALL ZSCAL( M, DCMPLX( SCALOC, ZERO ), C( 1, K ),
442: $ 1 )
443: CALL ZSCAL( M, DCMPLX( SCALOC, ZERO ), F( 1, K ),
444: $ 1 )
445: 40 CONTINUE
446: SCALE = SCALE*SCALOC
447: END IF
448: *
449: * Unpack solution vector(s)
450: *
451: C( I, J ) = RHS( 1 )
452: F( I, J ) = RHS( 2 )
453: *
454: * Substitute R(I, J) and L(I, J) into remaining equation.
455: *
456: DO 50 K = 1, J - 1
457: F( I, K ) = F( I, K ) + RHS( 1 )*DCONJG( B( K, J ) ) +
458: $ RHS( 2 )*DCONJG( E( K, J ) )
459: 50 CONTINUE
460: DO 60 K = I + 1, M
461: C( K, J ) = C( K, J ) - DCONJG( A( I, K ) )*RHS( 1 ) -
462: $ DCONJG( D( I, K ) )*RHS( 2 )
463: 60 CONTINUE
464: *
465: 70 CONTINUE
466: 80 CONTINUE
467: END IF
468: RETURN
469: *
470: * End of ZTGSY2
471: *
472: END
CVSweb interface <joel.bertrand@systella.fr>