1: SUBROUTINE ZGGHRD( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
2: $ LDQ, Z, LDZ, INFO )
3: *
4: * -- LAPACK routine (version 3.2) --
5: * -- LAPACK is a software package provided by Univ. of Tennessee, --
6: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
7: * November 2006
8: *
9: * .. Scalar Arguments ..
10: CHARACTER COMPQ, COMPZ
11: INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N
12: * ..
13: * .. Array Arguments ..
14: COMPLEX*16 A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
15: $ Z( LDZ, * )
16: * ..
17: *
18: * Purpose
19: * =======
20: *
21: * ZGGHRD reduces a pair of complex matrices (A,B) to generalized upper
22: * Hessenberg form using unitary transformations, where A is a
23: * general matrix and B is upper triangular. The form of the
24: * generalized eigenvalue problem is
25: * A*x = lambda*B*x,
26: * and B is typically made upper triangular by computing its QR
27: * factorization and moving the unitary matrix Q to the left side
28: * of the equation.
29: *
30: * This subroutine simultaneously reduces A to a Hessenberg matrix H:
31: * Q**H*A*Z = H
32: * and transforms B to another upper triangular matrix T:
33: * Q**H*B*Z = T
34: * in order to reduce the problem to its standard form
35: * H*y = lambda*T*y
36: * where y = Z**H*x.
37: *
38: * The unitary matrices Q and Z are determined as products of Givens
39: * rotations. They may either be formed explicitly, or they may be
40: * postmultiplied into input matrices Q1 and Z1, so that
41: * Q1 * A * Z1**H = (Q1*Q) * H * (Z1*Z)**H
42: * Q1 * B * Z1**H = (Q1*Q) * T * (Z1*Z)**H
43: * If Q1 is the unitary matrix from the QR factorization of B in the
44: * original equation A*x = lambda*B*x, then ZGGHRD reduces the original
45: * problem to generalized Hessenberg form.
46: *
47: * Arguments
48: * =========
49: *
50: * COMPQ (input) CHARACTER*1
51: * = 'N': do not compute Q;
52: * = 'I': Q is initialized to the unit matrix, and the
53: * unitary matrix Q is returned;
54: * = 'V': Q must contain a unitary matrix Q1 on entry,
55: * and the product Q1*Q is returned.
56: *
57: * COMPZ (input) CHARACTER*1
58: * = 'N': do not compute Q;
59: * = 'I': Q is initialized to the unit matrix, and the
60: * unitary matrix Q is returned;
61: * = 'V': Q must contain a unitary matrix Q1 on entry,
62: * and the product Q1*Q is returned.
63: *
64: * N (input) INTEGER
65: * The order of the matrices A and B. N >= 0.
66: *
67: * ILO (input) INTEGER
68: * IHI (input) INTEGER
69: * ILO and IHI mark the rows and columns of A which are to be
70: * reduced. It is assumed that A is already upper triangular
71: * in rows and columns 1:ILO-1 and IHI+1:N. ILO and IHI are
72: * normally set by a previous call to ZGGBAL; otherwise they
73: * should be set to 1 and N respectively.
74: * 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
75: *
76: * A (input/output) COMPLEX*16 array, dimension (LDA, N)
77: * On entry, the N-by-N general matrix to be reduced.
78: * On exit, the upper triangle and the first subdiagonal of A
79: * are overwritten with the upper Hessenberg matrix H, and the
80: * rest is set to zero.
81: *
82: * LDA (input) INTEGER
83: * The leading dimension of the array A. LDA >= max(1,N).
84: *
85: * B (input/output) COMPLEX*16 array, dimension (LDB, N)
86: * On entry, the N-by-N upper triangular matrix B.
87: * On exit, the upper triangular matrix T = Q**H B Z. The
88: * elements below the diagonal are set to zero.
89: *
90: * LDB (input) INTEGER
91: * The leading dimension of the array B. LDB >= max(1,N).
92: *
93: * Q (input/output) COMPLEX*16 array, dimension (LDQ, N)
94: * On entry, if COMPQ = 'V', the unitary matrix Q1, typically
95: * from the QR factorization of B.
96: * On exit, if COMPQ='I', the unitary matrix Q, and if
97: * COMPQ = 'V', the product Q1*Q.
98: * Not referenced if COMPQ='N'.
99: *
100: * LDQ (input) INTEGER
101: * The leading dimension of the array Q.
102: * LDQ >= N if COMPQ='V' or 'I'; LDQ >= 1 otherwise.
103: *
104: * Z (input/output) COMPLEX*16 array, dimension (LDZ, N)
105: * On entry, if COMPZ = 'V', the unitary matrix Z1.
106: * On exit, if COMPZ='I', the unitary matrix Z, and if
107: * COMPZ = 'V', the product Z1*Z.
108: * Not referenced if COMPZ='N'.
109: *
110: * LDZ (input) INTEGER
111: * The leading dimension of the array Z.
112: * LDZ >= N if COMPZ='V' or 'I'; LDZ >= 1 otherwise.
113: *
114: * INFO (output) INTEGER
115: * = 0: successful exit.
116: * < 0: if INFO = -i, the i-th argument had an illegal value.
117: *
118: * Further Details
119: * ===============
120: *
121: * This routine reduces A to Hessenberg and B to triangular form by
122: * an unblocked reduction, as described in _Matrix_Computations_,
123: * by Golub and van Loan (Johns Hopkins Press).
124: *
125: * =====================================================================
126: *
127: * .. Parameters ..
128: COMPLEX*16 CONE, CZERO
129: PARAMETER ( CONE = ( 1.0D+0, 0.0D+0 ),
130: $ CZERO = ( 0.0D+0, 0.0D+0 ) )
131: * ..
132: * .. Local Scalars ..
133: LOGICAL ILQ, ILZ
134: INTEGER ICOMPQ, ICOMPZ, JCOL, JROW
135: DOUBLE PRECISION C
136: COMPLEX*16 CTEMP, S
137: * ..
138: * .. External Functions ..
139: LOGICAL LSAME
140: EXTERNAL LSAME
141: * ..
142: * .. External Subroutines ..
143: EXTERNAL XERBLA, ZLARTG, ZLASET, ZROT
144: * ..
145: * .. Intrinsic Functions ..
146: INTRINSIC DCONJG, MAX
147: * ..
148: * .. Executable Statements ..
149: *
150: * Decode COMPQ
151: *
152: IF( LSAME( COMPQ, 'N' ) ) THEN
153: ILQ = .FALSE.
154: ICOMPQ = 1
155: ELSE IF( LSAME( COMPQ, 'V' ) ) THEN
156: ILQ = .TRUE.
157: ICOMPQ = 2
158: ELSE IF( LSAME( COMPQ, 'I' ) ) THEN
159: ILQ = .TRUE.
160: ICOMPQ = 3
161: ELSE
162: ICOMPQ = 0
163: END IF
164: *
165: * Decode COMPZ
166: *
167: IF( LSAME( COMPZ, 'N' ) ) THEN
168: ILZ = .FALSE.
169: ICOMPZ = 1
170: ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
171: ILZ = .TRUE.
172: ICOMPZ = 2
173: ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
174: ILZ = .TRUE.
175: ICOMPZ = 3
176: ELSE
177: ICOMPZ = 0
178: END IF
179: *
180: * Test the input parameters.
181: *
182: INFO = 0
183: IF( ICOMPQ.LE.0 ) THEN
184: INFO = -1
185: ELSE IF( ICOMPZ.LE.0 ) THEN
186: INFO = -2
187: ELSE IF( N.LT.0 ) THEN
188: INFO = -3
189: ELSE IF( ILO.LT.1 ) THEN
190: INFO = -4
191: ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THEN
192: INFO = -5
193: ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
194: INFO = -7
195: ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
196: INFO = -9
197: ELSE IF( ( ILQ .AND. LDQ.LT.N ) .OR. LDQ.LT.1 ) THEN
198: INFO = -11
199: ELSE IF( ( ILZ .AND. LDZ.LT.N ) .OR. LDZ.LT.1 ) THEN
200: INFO = -13
201: END IF
202: IF( INFO.NE.0 ) THEN
203: CALL XERBLA( 'ZGGHRD', -INFO )
204: RETURN
205: END IF
206: *
207: * Initialize Q and Z if desired.
208: *
209: IF( ICOMPQ.EQ.3 )
210: $ CALL ZLASET( 'Full', N, N, CZERO, CONE, Q, LDQ )
211: IF( ICOMPZ.EQ.3 )
212: $ CALL ZLASET( 'Full', N, N, CZERO, CONE, Z, LDZ )
213: *
214: * Quick return if possible
215: *
216: IF( N.LE.1 )
217: $ RETURN
218: *
219: * Zero out lower triangle of B
220: *
221: DO 20 JCOL = 1, N - 1
222: DO 10 JROW = JCOL + 1, N
223: B( JROW, JCOL ) = CZERO
224: 10 CONTINUE
225: 20 CONTINUE
226: *
227: * Reduce A and B
228: *
229: DO 40 JCOL = ILO, IHI - 2
230: *
231: DO 30 JROW = IHI, JCOL + 2, -1
232: *
233: * Step 1: rotate rows JROW-1, JROW to kill A(JROW,JCOL)
234: *
235: CTEMP = A( JROW-1, JCOL )
236: CALL ZLARTG( CTEMP, A( JROW, JCOL ), C, S,
237: $ A( JROW-1, JCOL ) )
238: A( JROW, JCOL ) = CZERO
239: CALL ZROT( N-JCOL, A( JROW-1, JCOL+1 ), LDA,
240: $ A( JROW, JCOL+1 ), LDA, C, S )
241: CALL ZROT( N+2-JROW, B( JROW-1, JROW-1 ), LDB,
242: $ B( JROW, JROW-1 ), LDB, C, S )
243: IF( ILQ )
244: $ CALL ZROT( N, Q( 1, JROW-1 ), 1, Q( 1, JROW ), 1, C,
245: $ DCONJG( S ) )
246: *
247: * Step 2: rotate columns JROW, JROW-1 to kill B(JROW,JROW-1)
248: *
249: CTEMP = B( JROW, JROW )
250: CALL ZLARTG( CTEMP, B( JROW, JROW-1 ), C, S,
251: $ B( JROW, JROW ) )
252: B( JROW, JROW-1 ) = CZERO
253: CALL ZROT( IHI, A( 1, JROW ), 1, A( 1, JROW-1 ), 1, C, S )
254: CALL ZROT( JROW-1, B( 1, JROW ), 1, B( 1, JROW-1 ), 1, C,
255: $ S )
256: IF( ILZ )
257: $ CALL ZROT( N, Z( 1, JROW ), 1, Z( 1, JROW-1 ), 1, C, S )
258: 30 CONTINUE
259: 40 CONTINUE
260: *
261: RETURN
262: *
263: * End of ZGGHRD
264: *
265: END
CVSweb interface <joel.bertrand@systella.fr>