1 *> \brief \b CTGEX2 swaps adjacent diagonal blocks in an upper (quasi) triangular matrix pair by an unitary equivalence transformation.
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download CTGEX2 + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ctgex2.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ctgex2.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ctgex2.f">
21 * SUBROUTINE CTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,
24 * .. Scalar Arguments ..
25 * LOGICAL WANTQ, WANTZ
26 * INTEGER INFO, J1, LDA, LDB, LDQ, LDZ, N
28 * .. Array Arguments ..
29 * COMPLEX A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
39 *> CTGEX2 swaps adjacent diagonal 1 by 1 blocks (A11,B11) and (A22,B22)
40 *> in an upper triangular matrix pair (A, B) by an unitary equivalence
43 *> (A, B) must be in generalized Schur canonical form, that is, A and
44 *> B are both upper triangular.
46 *> Optionally, the matrices Q and Z of generalized Schur vectors are
49 *> Q(in) * A(in) * Z(in)**H = Q(out) * A(out) * Z(out)**H
50 *> Q(in) * B(in) * Z(in)**H = Q(out) * B(out) * Z(out)**H
60 *> .TRUE. : update the left transformation matrix Q;
61 *> .FALSE.: do not update Q.
67 *> .TRUE. : update the right transformation matrix Z;
68 *> .FALSE.: do not update Z.
74 *> The order of the matrices A and B. N >= 0.
79 *> A is COMPLEX arrays, dimensions (LDA,N)
80 *> On entry, the matrix A in the pair (A, B).
81 *> On exit, the updated matrix A.
87 *> The leading dimension of the array A. LDA >= max(1,N).
92 *> B is COMPLEX arrays, dimensions (LDB,N)
93 *> On entry, the matrix B in the pair (A, B).
94 *> On exit, the updated matrix B.
100 *> The leading dimension of the array B. LDB >= max(1,N).
105 *> Q is COMPLEX array, dimension (LDZ,N)
106 *> If WANTQ = .TRUE, on entry, the unitary matrix Q. On exit,
107 *> the updated matrix Q.
108 *> Not referenced if WANTQ = .FALSE..
114 *> The leading dimension of the array Q. LDQ >= 1;
115 *> If WANTQ = .TRUE., LDQ >= N.
120 *> Z is COMPLEX array, dimension (LDZ,N)
121 *> If WANTZ = .TRUE, on entry, the unitary matrix Z. On exit,
122 *> the updated matrix Z.
123 *> Not referenced if WANTZ = .FALSE..
129 *> The leading dimension of the array Z. LDZ >= 1;
130 *> If WANTZ = .TRUE., LDZ >= N.
136 *> The index to the first block (A11, B11).
142 *> =0: Successful exit.
143 *> =1: The transformed matrix pair (A, B) would be too far
144 *> from generalized Schur form; the problem is ill-
151 *> \author Univ. of Tennessee
152 *> \author Univ. of California Berkeley
153 *> \author Univ. of Colorado Denver
156 *> \date September 2012
158 *> \ingroup complexGEauxiliary
160 *> \par Further Details:
161 * =====================
163 *> In the current code both weak and strong stability tests are
164 *> performed. The user can omit the strong stability test by changing
165 *> the internal logical parameter WANDS to .FALSE.. See ref. [2] for
168 *> \par Contributors:
171 *> Bo Kagstrom and Peter Poromaa, Department of Computing Science,
172 *> Umea University, S-901 87 Umea, Sweden.
177 *> [1] B. Kagstrom; A Direct Method for Reordering Eigenvalues in the
178 *> Generalized Real Schur Form of a Regular Matrix Pair (A, B), in
179 *> M.S. Moonen et al (eds), Linear Algebra for Large Scale and
180 *> Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218.
182 *> [2] B. Kagstrom and P. Poromaa; Computing Eigenspaces with Specified
183 *> Eigenvalues of a Regular Matrix Pair (A, B) and Condition
184 *> Estimation: Theory, Algorithms and Software, Report UMINF-94.04,
185 *> Department of Computing Science, Umea University, S-901 87 Umea,
186 *> Sweden, 1994. Also as LAPACK Working Note 87. To appear in
187 *> Numerical Algorithms, 1996.
189 * =====================================================================
190 SUBROUTINE CTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,
193 * -- LAPACK auxiliary routine (version 3.4.2) --
194 * -- LAPACK is a software package provided by Univ. of Tennessee, --
195 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
198 * .. Scalar Arguments ..
200 INTEGER INFO, J1, LDA, LDB, LDQ, LDZ, N
202 * .. Array Arguments ..
203 COMPLEX A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
207 * =====================================================================
211 PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ),
212 $ CONE = ( 1.0E+0, 0.0E+0 ) )
214 PARAMETER ( TWENTY = 2.0E+1 )
216 PARAMETER ( LDST = 2 )
218 PARAMETER ( WANDS = .TRUE. )
220 * .. Local Scalars ..
223 REAL CQ, CZ, EPS, SA, SB, SCALE, SMLNUM, SS, SUM,
225 COMPLEX CDUM, F, G, SQ, SZ
228 COMPLEX S( LDST, LDST ), T( LDST, LDST ), WORK( 8 )
230 * .. External Functions ..
234 * .. External Subroutines ..
235 EXTERNAL CLACPY, CLARTG, CLASSQ, CROT
237 * .. Intrinsic Functions ..
238 INTRINSIC ABS, CONJG, MAX, REAL, SQRT
240 * .. Executable Statements ..
244 * Quick return if possible
253 * Make a local copy of selected block in (A, B)
255 CALL CLACPY( 'Full', M, M, A( J1, J1 ), LDA, S, LDST )
256 CALL CLACPY( 'Full', M, M, B( J1, J1 ), LDB, T, LDST )
258 * Compute the threshold for testing the acceptance of swapping.
261 SMLNUM = SLAMCH( 'S' ) / EPS
262 SCALE = REAL( CZERO )
264 CALL CLACPY( 'Full', M, M, S, LDST, WORK, M )
265 CALL CLACPY( 'Full', M, M, T, LDST, WORK( M*M+1 ), M )
266 CALL CLASSQ( 2*M*M, WORK, 1, SCALE, SUM )
267 SA = SCALE*SQRT( SUM )
269 * THRES has been changed from
270 * THRESH = MAX( TEN*EPS*SA, SMLNUM )
272 * THRESH = MAX( TWENTY*EPS*SA, SMLNUM )
274 * "Bug" reported by Ondra Kamenik, confirmed by Julie Langou, fixed by
275 * Jim Demmel and Guillaume Revy. See forum post 1783.
277 THRESH = MAX( TWENTY*EPS*SA, SMLNUM )
279 * Compute unitary QL and RQ that swap 1-by-1 and 1-by-1 blocks
280 * using Givens rotations and perform the swap tentatively.
282 F = S( 2, 2 )*T( 1, 1 ) - T( 2, 2 )*S( 1, 1 )
283 G = S( 2, 2 )*T( 1, 2 ) - T( 2, 2 )*S( 1, 2 )
284 SA = ABS( S( 2, 2 ) )
285 SB = ABS( T( 2, 2 ) )
286 CALL CLARTG( G, F, CZ, SZ, CDUM )
288 CALL CROT( 2, S( 1, 1 ), 1, S( 1, 2 ), 1, CZ, CONJG( SZ ) )
289 CALL CROT( 2, T( 1, 1 ), 1, T( 1, 2 ), 1, CZ, CONJG( SZ ) )
291 CALL CLARTG( S( 1, 1 ), S( 2, 1 ), CQ, SQ, CDUM )
293 CALL CLARTG( T( 1, 1 ), T( 2, 1 ), CQ, SQ, CDUM )
295 CALL CROT( 2, S( 1, 1 ), LDST, S( 2, 1 ), LDST, CQ, SQ )
296 CALL CROT( 2, T( 1, 1 ), LDST, T( 2, 1 ), LDST, CQ, SQ )
298 * Weak stability test: |S21| + |T21| <= O(EPS F-norm((S, T)))
300 WS = ABS( S( 2, 1 ) ) + ABS( T( 2, 1 ) )
307 * Strong stability test:
308 * F-norm((A-QL**H*S*QR, B-QL**H*T*QR)) <= O(EPS*F-norm((A, B)))
310 CALL CLACPY( 'Full', M, M, S, LDST, WORK, M )
311 CALL CLACPY( 'Full', M, M, T, LDST, WORK( M*M+1 ), M )
312 CALL CROT( 2, WORK, 1, WORK( 3 ), 1, CZ, -CONJG( SZ ) )
313 CALL CROT( 2, WORK( 5 ), 1, WORK( 7 ), 1, CZ, -CONJG( SZ ) )
314 CALL CROT( 2, WORK, 2, WORK( 2 ), 2, CQ, -SQ )
315 CALL CROT( 2, WORK( 5 ), 2, WORK( 6 ), 2, CQ, -SQ )
317 WORK( I ) = WORK( I ) - A( J1+I-1, J1 )
318 WORK( I+2 ) = WORK( I+2 ) - A( J1+I-1, J1+1 )
319 WORK( I+4 ) = WORK( I+4 ) - B( J1+I-1, J1 )
320 WORK( I+6 ) = WORK( I+6 ) - B( J1+I-1, J1+1 )
322 SCALE = REAL( CZERO )
324 CALL CLASSQ( 2*M*M, WORK, 1, SCALE, SUM )
325 SS = SCALE*SQRT( SUM )
326 STRONG = SS.LE.THRESH
331 * If the swap is accepted ("weakly" and "strongly"), apply the
332 * equivalence transformations to the original matrix pair (A,B)
334 CALL CROT( J1+1, A( 1, J1 ), 1, A( 1, J1+1 ), 1, CZ, CONJG( SZ ) )
335 CALL CROT( J1+1, B( 1, J1 ), 1, B( 1, J1+1 ), 1, CZ, CONJG( SZ ) )
336 CALL CROT( N-J1+1, A( J1, J1 ), LDA, A( J1+1, J1 ), LDA, CQ, SQ )
337 CALL CROT( N-J1+1, B( J1, J1 ), LDB, B( J1+1, J1 ), LDB, CQ, SQ )
339 * Set N1 by N2 (2,1) blocks to 0
341 A( J1+1, J1 ) = CZERO
342 B( J1+1, J1 ) = CZERO
344 * Accumulate transformations into Q and Z if requested.
347 $ CALL CROT( N, Z( 1, J1 ), 1, Z( 1, J1+1 ), 1, CZ, CONJG( SZ ) )
349 $ CALL CROT( N, Q( 1, J1 ), 1, Q( 1, J1+1 ), 1, CQ, CONJG( SQ ) )
351 * Exit with INFO = 0 if swap was successfully performed.
355 * Exit with INFO = 1 if swap was rejected.