1 *> \brief \b DLAEXC swaps adjacent diagonal blocks of a real upper quasi-triangular matrix in Schur canonical form, by an orthogonal similarity transformation.
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download DLAEXC + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaexc.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaexc.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaexc.f">
21 * SUBROUTINE DLAEXC( WANTQ, N, T, LDT, Q, LDQ, J1, N1, N2, WORK,
24 * .. Scalar Arguments ..
26 * INTEGER INFO, J1, LDQ, LDT, N, N1, N2
28 * .. Array Arguments ..
29 * DOUBLE PRECISION Q( LDQ, * ), T( LDT, * ), WORK( * )
38 *> DLAEXC swaps adjacent diagonal blocks T11 and T22 of order 1 or 2 in
39 *> an upper quasi-triangular matrix T by an orthogonal similarity
42 *> T must be in Schur canonical form, that is, block upper triangular
43 *> with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block
44 *> has its diagonal elemnts equal and its off-diagonal elements of
54 *> = .TRUE. : accumulate the transformation in the matrix Q;
55 *> = .FALSE.: do not accumulate the transformation.
61 *> The order of the matrix T. N >= 0.
66 *> T is DOUBLE PRECISION array, dimension (LDT,N)
67 *> On entry, the upper quasi-triangular matrix T, in Schur
69 *> On exit, the updated matrix T, again in Schur canonical form.
75 *> The leading dimension of the array T. LDT >= max(1,N).
80 *> Q is DOUBLE PRECISION array, dimension (LDQ,N)
81 *> On entry, if WANTQ is .TRUE., the orthogonal matrix Q.
82 *> On exit, if WANTQ is .TRUE., the updated matrix Q.
83 *> If WANTQ is .FALSE., Q is not referenced.
89 *> The leading dimension of the array Q.
90 *> LDQ >= 1; and if WANTQ is .TRUE., LDQ >= N.
96 *> The index of the first row of the first block T11.
102 *> The order of the first block T11. N1 = 0, 1 or 2.
108 *> The order of the second block T22. N2 = 0, 1 or 2.
113 *> WORK is DOUBLE PRECISION array, dimension (N)
119 *> = 0: successful exit
120 *> = 1: the transformed matrix T would be too far from Schur
121 *> form; the blocks are not swapped and T and Q are
128 *> \author Univ. of Tennessee
129 *> \author Univ. of California Berkeley
130 *> \author Univ. of Colorado Denver
133 *> \date September 2012
135 *> \ingroup doubleOTHERauxiliary
137 * =====================================================================
138 SUBROUTINE DLAEXC( WANTQ, N, T, LDT, Q, LDQ, J1, N1, N2, WORK,
141 * -- LAPACK auxiliary routine (version 3.4.2) --
142 * -- LAPACK is a software package provided by Univ. of Tennessee, --
143 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
146 * .. Scalar Arguments ..
148 INTEGER INFO, J1, LDQ, LDT, N, N1, N2
150 * .. Array Arguments ..
151 DOUBLE PRECISION Q( LDQ, * ), T( LDT, * ), WORK( * )
154 * =====================================================================
157 DOUBLE PRECISION ZERO, ONE
158 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
160 PARAMETER ( TEN = 1.0D+1 )
162 PARAMETER ( LDD = 4, LDX = 2 )
164 * .. Local Scalars ..
165 INTEGER IERR, J2, J3, J4, K, ND
166 DOUBLE PRECISION CS, DNORM, EPS, SCALE, SMLNUM, SN, T11, T22,
167 $ T33, TAU, TAU1, TAU2, TEMP, THRESH, WI1, WI2,
171 DOUBLE PRECISION D( LDD, 4 ), U( 3 ), U1( 3 ), U2( 3 ),
174 * .. External Functions ..
175 DOUBLE PRECISION DLAMCH, DLANGE
176 EXTERNAL DLAMCH, DLANGE
178 * .. External Subroutines ..
179 EXTERNAL DLACPY, DLANV2, DLARFG, DLARFX, DLARTG, DLASY2,
182 * .. Intrinsic Functions ..
185 * .. Executable Statements ..
189 * Quick return if possible
191 IF( N.EQ.0 .OR. N1.EQ.0 .OR. N2.EQ.0 )
200 IF( N1.EQ.1 .AND. N2.EQ.1 ) THEN
202 * Swap two 1-by-1 blocks.
207 * Determine the transformation to perform the interchange.
209 CALL DLARTG( T( J1, J2 ), T22-T11, CS, SN, TEMP )
211 * Apply transformation to the matrix T.
214 $ CALL DROT( N-J1-1, T( J1, J3 ), LDT, T( J2, J3 ), LDT, CS,
216 CALL DROT( J1-1, T( 1, J1 ), 1, T( 1, J2 ), 1, CS, SN )
223 * Accumulate transformation in the matrix Q.
225 CALL DROT( N, Q( 1, J1 ), 1, Q( 1, J2 ), 1, CS, SN )
230 * Swapping involves at least one 2-by-2 block.
232 * Copy the diagonal block of order N1+N2 to the local array D
233 * and compute its norm.
236 CALL DLACPY( 'Full', ND, ND, T( J1, J1 ), LDT, D, LDD )
237 DNORM = DLANGE( 'Max', ND, ND, D, LDD, WORK )
239 * Compute machine-dependent threshold for test for accepting
243 SMLNUM = DLAMCH( 'S' ) / EPS
244 THRESH = MAX( TEN*EPS*DNORM, SMLNUM )
246 * Solve T11*X - X*T22 = scale*T12 for X.
248 CALL DLASY2( .FALSE., .FALSE., -1, N1, N2, D, LDD,
249 $ D( N1+1, N1+1 ), LDD, D( 1, N1+1 ), LDD, SCALE, X,
252 * Swap the adjacent diagonal blocks.
255 GO TO ( 10, 20, 30 )K
259 * N1 = 1, N2 = 2: generate elementary reflector H so that:
261 * ( scale, X11, X12 ) H = ( 0, 0, * )
266 CALL DLARFG( 3, U( 3 ), U, 1, TAU )
270 * Perform swap provisionally on diagonal block in D.
272 CALL DLARFX( 'L', 3, 3, U, TAU, D, LDD, WORK )
273 CALL DLARFX( 'R', 3, 3, U, TAU, D, LDD, WORK )
275 * Test whether to reject swap.
277 IF( MAX( ABS( D( 3, 1 ) ), ABS( D( 3, 2 ) ), ABS( D( 3,
278 $ 3 )-T11 ) ).GT.THRESH )GO TO 50
280 * Accept swap: apply transformation to the entire matrix T.
282 CALL DLARFX( 'L', 3, N-J1+1, U, TAU, T( J1, J1 ), LDT, WORK )
283 CALL DLARFX( 'R', J2, 3, U, TAU, T( 1, J1 ), LDT, WORK )
291 * Accumulate transformation in the matrix Q.
293 CALL DLARFX( 'R', N, 3, U, TAU, Q( 1, J1 ), LDQ, WORK )
299 * N1 = 2, N2 = 1: generate elementary reflector H so that:
308 CALL DLARFG( 3, U( 1 ), U( 2 ), 1, TAU )
312 * Perform swap provisionally on diagonal block in D.
314 CALL DLARFX( 'L', 3, 3, U, TAU, D, LDD, WORK )
315 CALL DLARFX( 'R', 3, 3, U, TAU, D, LDD, WORK )
317 * Test whether to reject swap.
319 IF( MAX( ABS( D( 2, 1 ) ), ABS( D( 3, 1 ) ), ABS( D( 1,
320 $ 1 )-T33 ) ).GT.THRESH )GO TO 50
322 * Accept swap: apply transformation to the entire matrix T.
324 CALL DLARFX( 'R', J3, 3, U, TAU, T( 1, J1 ), LDT, WORK )
325 CALL DLARFX( 'L', 3, N-J1, U, TAU, T( J1, J2 ), LDT, WORK )
333 * Accumulate transformation in the matrix Q.
335 CALL DLARFX( 'R', N, 3, U, TAU, Q( 1, J1 ), LDQ, WORK )
341 * N1 = 2, N2 = 2: generate elementary reflectors H(1) and H(2) so
344 * H(2) H(1) ( -X11 -X12 ) = ( * * )
345 * ( -X21 -X22 ) ( 0 * )
346 * ( scale 0 ) ( 0 0 )
347 * ( 0 scale ) ( 0 0 )
352 CALL DLARFG( 3, U1( 1 ), U1( 2 ), 1, TAU1 )
355 TEMP = -TAU1*( X( 1, 2 )+U1( 2 )*X( 2, 2 ) )
356 U2( 1 ) = -TEMP*U1( 2 ) - X( 2, 2 )
357 U2( 2 ) = -TEMP*U1( 3 )
359 CALL DLARFG( 3, U2( 1 ), U2( 2 ), 1, TAU2 )
362 * Perform swap provisionally on diagonal block in D.
364 CALL DLARFX( 'L', 3, 4, U1, TAU1, D, LDD, WORK )
365 CALL DLARFX( 'R', 4, 3, U1, TAU1, D, LDD, WORK )
366 CALL DLARFX( 'L', 3, 4, U2, TAU2, D( 2, 1 ), LDD, WORK )
367 CALL DLARFX( 'R', 4, 3, U2, TAU2, D( 1, 2 ), LDD, WORK )
369 * Test whether to reject swap.
371 IF( MAX( ABS( D( 3, 1 ) ), ABS( D( 3, 2 ) ), ABS( D( 4, 1 ) ),
372 $ ABS( D( 4, 2 ) ) ).GT.THRESH )GO TO 50
374 * Accept swap: apply transformation to the entire matrix T.
376 CALL DLARFX( 'L', 3, N-J1+1, U1, TAU1, T( J1, J1 ), LDT, WORK )
377 CALL DLARFX( 'R', J4, 3, U1, TAU1, T( 1, J1 ), LDT, WORK )
378 CALL DLARFX( 'L', 3, N-J1+1, U2, TAU2, T( J2, J1 ), LDT, WORK )
379 CALL DLARFX( 'R', J4, 3, U2, TAU2, T( 1, J2 ), LDT, WORK )
388 * Accumulate transformation in the matrix Q.
390 CALL DLARFX( 'R', N, 3, U1, TAU1, Q( 1, J1 ), LDQ, WORK )
391 CALL DLARFX( 'R', N, 3, U2, TAU2, Q( 1, J2 ), LDQ, WORK )
398 * Standardize new 2-by-2 block T11
400 CALL DLANV2( T( J1, J1 ), T( J1, J2 ), T( J2, J1 ),
401 $ T( J2, J2 ), WR1, WI1, WR2, WI2, CS, SN )
402 CALL DROT( N-J1-1, T( J1, J1+2 ), LDT, T( J2, J1+2 ), LDT,
404 CALL DROT( J1-1, T( 1, J1 ), 1, T( 1, J2 ), 1, CS, SN )
406 $ CALL DROT( N, Q( 1, J1 ), 1, Q( 1, J2 ), 1, CS, SN )
411 * Standardize new 2-by-2 block T22
415 CALL DLANV2( T( J3, J3 ), T( J3, J4 ), T( J4, J3 ),
416 $ T( J4, J4 ), WR1, WI1, WR2, WI2, CS, SN )
418 $ CALL DROT( N-J3-1, T( J3, J3+2 ), LDT, T( J4, J3+2 ),
420 CALL DROT( J3-1, T( 1, J3 ), 1, T( 1, J4 ), 1, CS, SN )
422 $ CALL DROT( N, Q( 1, J3 ), 1, Q( 1, J4 ), 1, CS, SN )
428 * Exit with INFO = 1 if swap was rejected.