3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download DTRSNA + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrsna.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrsna.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrsna.f">
21 * SUBROUTINE DTRSNA( JOB, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
22 * LDVR, S, SEP, MM, M, WORK, LDWORK, IWORK,
25 * .. Scalar Arguments ..
26 * CHARACTER HOWMNY, JOB
27 * INTEGER INFO, LDT, LDVL, LDVR, LDWORK, M, MM, N
29 * .. Array Arguments ..
32 * DOUBLE PRECISION S( * ), SEP( * ), T( LDT, * ), VL( LDVL, * ),
33 * $ VR( LDVR, * ), WORK( LDWORK, * )
42 *> DTRSNA estimates reciprocal condition numbers for specified
43 *> eigenvalues and/or right eigenvectors of a real upper
44 *> quasi-triangular matrix T (or of any matrix Q*T*Q**T with Q
47 *> T must be in Schur canonical form (as returned by DHSEQR), that is,
48 *> block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
49 *> 2-by-2 diagonal block has its diagonal elements equal and its
50 *> off-diagonal elements of opposite sign.
59 *> Specifies whether condition numbers are required for
60 *> eigenvalues (S) or eigenvectors (SEP):
61 *> = 'E': for eigenvalues only (S);
62 *> = 'V': for eigenvectors only (SEP);
63 *> = 'B': for both eigenvalues and eigenvectors (S and SEP).
68 *> HOWMNY is CHARACTER*1
69 *> = 'A': compute condition numbers for all eigenpairs;
70 *> = 'S': compute condition numbers for selected eigenpairs
71 *> specified by the array SELECT.
76 *> SELECT is LOGICAL array, dimension (N)
77 *> If HOWMNY = 'S', SELECT specifies the eigenpairs for which
78 *> condition numbers are required. To select condition numbers
79 *> for the eigenpair corresponding to a real eigenvalue w(j),
80 *> SELECT(j) must be set to .TRUE.. To select condition numbers
81 *> corresponding to a complex conjugate pair of eigenvalues w(j)
82 *> and w(j+1), either SELECT(j) or SELECT(j+1) or both, must be
84 *> If HOWMNY = 'A', SELECT is not referenced.
90 *> The order of the matrix T. N >= 0.
95 *> T is DOUBLE PRECISION array, dimension (LDT,N)
96 *> The upper quasi-triangular matrix T, in Schur canonical form.
102 *> The leading dimension of the array T. LDT >= max(1,N).
107 *> VL is DOUBLE PRECISION array, dimension (LDVL,M)
108 *> If JOB = 'E' or 'B', VL must contain left eigenvectors of T
109 *> (or of any Q*T*Q**T with Q orthogonal), corresponding to the
110 *> eigenpairs specified by HOWMNY and SELECT. The eigenvectors
111 *> must be stored in consecutive columns of VL, as returned by
113 *> If JOB = 'V', VL is not referenced.
119 *> The leading dimension of the array VL.
120 *> LDVL >= 1; and if JOB = 'E' or 'B', LDVL >= N.
125 *> VR is DOUBLE PRECISION array, dimension (LDVR,M)
126 *> If JOB = 'E' or 'B', VR must contain right eigenvectors of T
127 *> (or of any Q*T*Q**T with Q orthogonal), corresponding to the
128 *> eigenpairs specified by HOWMNY and SELECT. The eigenvectors
129 *> must be stored in consecutive columns of VR, as returned by
131 *> If JOB = 'V', VR is not referenced.
137 *> The leading dimension of the array VR.
138 *> LDVR >= 1; and if JOB = 'E' or 'B', LDVR >= N.
143 *> S is DOUBLE PRECISION array, dimension (MM)
144 *> If JOB = 'E' or 'B', the reciprocal condition numbers of the
145 *> selected eigenvalues, stored in consecutive elements of the
146 *> array. For a complex conjugate pair of eigenvalues two
147 *> consecutive elements of S are set to the same value. Thus
148 *> S(j), SEP(j), and the j-th columns of VL and VR all
149 *> correspond to the same eigenpair (but not in general the
150 *> j-th eigenpair, unless all eigenpairs are selected).
151 *> If JOB = 'V', S is not referenced.
156 *> SEP is DOUBLE PRECISION array, dimension (MM)
157 *> If JOB = 'V' or 'B', the estimated reciprocal condition
158 *> numbers of the selected eigenvectors, stored in consecutive
159 *> elements of the array. For a complex eigenvector two
160 *> consecutive elements of SEP are set to the same value. If
161 *> the eigenvalues cannot be reordered to compute SEP(j), SEP(j)
162 *> is set to 0; this can only occur when the true value would be
163 *> very small anyway.
164 *> If JOB = 'E', SEP is not referenced.
170 *> The number of elements in the arrays S (if JOB = 'E' or 'B')
171 *> and/or SEP (if JOB = 'V' or 'B'). MM >= M.
177 *> The number of elements of the arrays S and/or SEP actually
178 *> used to store the estimated condition numbers.
179 *> If HOWMNY = 'A', M is set to N.
184 *> WORK is DOUBLE PRECISION array, dimension (LDWORK,N+6)
185 *> If JOB = 'E', WORK is not referenced.
191 *> The leading dimension of the array WORK.
192 *> LDWORK >= 1; and if JOB = 'V' or 'B', LDWORK >= N.
197 *> IWORK is INTEGER array, dimension (2*(N-1))
198 *> If JOB = 'E', IWORK is not referenced.
204 *> = 0: successful exit
205 *> < 0: if INFO = -i, the i-th argument had an illegal value
211 *> \author Univ. of Tennessee
212 *> \author Univ. of California Berkeley
213 *> \author Univ. of Colorado Denver
216 *> \date November 2011
218 *> \ingroup doubleOTHERcomputational
220 *> \par Further Details:
221 * =====================
225 *> The reciprocal of the condition number of an eigenvalue lambda is
228 *> S(lambda) = |v**T*u| / (norm(u)*norm(v))
230 *> where u and v are the right and left eigenvectors of T corresponding
231 *> to lambda; v**T denotes the transpose of v, and norm(u)
232 *> denotes the Euclidean norm. These reciprocal condition numbers always
233 *> lie between zero (very badly conditioned) and one (very well
234 *> conditioned). If n = 1, S(lambda) is defined to be 1.
236 *> An approximate error bound for a computed eigenvalue W(i) is given by
238 *> EPS * norm(T) / S(i)
240 *> where EPS is the machine precision.
242 *> The reciprocal of the condition number of the right eigenvector u
243 *> corresponding to lambda is defined as follows. Suppose
248 *> Then the reciprocal condition number is
250 *> SEP( lambda, T22 ) = sigma-min( T22 - lambda*I )
252 *> where sigma-min denotes the smallest singular value. We approximate
253 *> the smallest singular value by the reciprocal of an estimate of the
254 *> one-norm of the inverse of T22 - lambda*I. If n = 1, SEP(1) is
255 *> defined to be abs(T(1,1)).
257 *> An approximate error bound for a computed right eigenvector VR(i)
260 *> EPS * norm(T) / SEP(i)
263 * =====================================================================
264 SUBROUTINE DTRSNA( JOB, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
265 $ LDVR, S, SEP, MM, M, WORK, LDWORK, IWORK,
268 * -- LAPACK computational routine (version 3.4.0) --
269 * -- LAPACK is a software package provided by Univ. of Tennessee, --
270 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
273 * .. Scalar Arguments ..
274 CHARACTER HOWMNY, JOB
275 INTEGER INFO, LDT, LDVL, LDVR, LDWORK, M, MM, N
277 * .. Array Arguments ..
280 DOUBLE PRECISION S( * ), SEP( * ), T( LDT, * ), VL( LDVL, * ),
281 $ VR( LDVR, * ), WORK( LDWORK, * )
284 * =====================================================================
287 DOUBLE PRECISION ZERO, ONE, TWO
288 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )
290 * .. Local Scalars ..
291 LOGICAL PAIR, SOMCON, WANTBH, WANTS, WANTSP
292 INTEGER I, IERR, IFST, ILST, J, K, KASE, KS, N2, NN
293 DOUBLE PRECISION BIGNUM, COND, CS, DELTA, DUMM, EPS, EST, LNRM,
294 $ MU, PROD, PROD1, PROD2, RNRM, SCALE, SMLNUM, SN
298 DOUBLE PRECISION DUMMY( 1 )
300 * .. External Functions ..
302 DOUBLE PRECISION DDOT, DLAMCH, DLAPY2, DNRM2
303 EXTERNAL LSAME, DDOT, DLAMCH, DLAPY2, DNRM2
305 * .. External Subroutines ..
306 EXTERNAL DLACN2, DLACPY, DLAQTR, DTREXC, XERBLA
308 * .. Intrinsic Functions ..
309 INTRINSIC ABS, MAX, SQRT
311 * .. Executable Statements ..
313 * Decode and test the input parameters
315 WANTBH = LSAME( JOB, 'B' )
316 WANTS = LSAME( JOB, 'E' ) .OR. WANTBH
317 WANTSP = LSAME( JOB, 'V' ) .OR. WANTBH
319 SOMCON = LSAME( HOWMNY, 'S' )
322 IF( .NOT.WANTS .AND. .NOT.WANTSP ) THEN
324 ELSE IF( .NOT.LSAME( HOWMNY, 'A' ) .AND. .NOT.SOMCON ) THEN
326 ELSE IF( N.LT.0 ) THEN
328 ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
330 ELSE IF( LDVL.LT.1 .OR. ( WANTS .AND. LDVL.LT.N ) ) THEN
332 ELSE IF( LDVR.LT.1 .OR. ( WANTS .AND. LDVR.LT.N ) ) THEN
336 * Set M to the number of eigenpairs for which condition numbers
337 * are required, and test MM.
347 IF( T( K+1, K ).EQ.ZERO ) THEN
352 IF( SELECT( K ) .OR. SELECT( K+1 ) )
367 ELSE IF( LDWORK.LT.1 .OR. ( WANTSP .AND. LDWORK.LT.N ) ) THEN
372 CALL XERBLA( 'DTRSNA', -INFO )
376 * Quick return if possible
383 IF( .NOT.SELECT( 1 ) )
389 $ SEP( 1 ) = ABS( T( 1, 1 ) )
393 * Get machine constants
396 SMLNUM = DLAMCH( 'S' ) / EPS
397 BIGNUM = ONE / SMLNUM
398 CALL DLABAD( SMLNUM, BIGNUM )
404 * Determine whether T(k,k) begins a 1-by-1 or 2-by-2 block.
411 $ PAIR = T( K+1, K ).NE.ZERO
414 * Determine whether condition numbers are required for the k-th
419 IF( .NOT.SELECT( K ) .AND. .NOT.SELECT( K+1 ) )
422 IF( .NOT.SELECT( K ) )
431 * Compute the reciprocal condition number of the k-th
438 PROD = DDOT( N, VR( 1, KS ), 1, VL( 1, KS ), 1 )
439 RNRM = DNRM2( N, VR( 1, KS ), 1 )
440 LNRM = DNRM2( N, VL( 1, KS ), 1 )
441 S( KS ) = ABS( PROD ) / ( RNRM*LNRM )
444 * Complex eigenvalue.
446 PROD1 = DDOT( N, VR( 1, KS ), 1, VL( 1, KS ), 1 )
447 PROD1 = PROD1 + DDOT( N, VR( 1, KS+1 ), 1, VL( 1, KS+1 ),
449 PROD2 = DDOT( N, VL( 1, KS ), 1, VR( 1, KS+1 ), 1 )
450 PROD2 = PROD2 - DDOT( N, VL( 1, KS+1 ), 1, VR( 1, KS ),
452 RNRM = DLAPY2( DNRM2( N, VR( 1, KS ), 1 ),
453 $ DNRM2( N, VR( 1, KS+1 ), 1 ) )
454 LNRM = DLAPY2( DNRM2( N, VL( 1, KS ), 1 ),
455 $ DNRM2( N, VL( 1, KS+1 ), 1 ) )
456 COND = DLAPY2( PROD1, PROD2 ) / ( RNRM*LNRM )
464 * Estimate the reciprocal condition number of the k-th
467 * Copy the matrix T to the array WORK and swap the diagonal
468 * block beginning at T(k,k) to the (1,1) position.
470 CALL DLACPY( 'Full', N, N, T, LDT, WORK, LDWORK )
473 CALL DTREXC( 'No Q', N, WORK, LDWORK, DUMMY, 1, IFST, ILST,
474 $ WORK( 1, N+1 ), IERR )
476 IF( IERR.EQ.1 .OR. IERR.EQ.2 ) THEN
478 * Could not swap because blocks not well separated
484 * Reordering successful
486 IF( WORK( 2, 1 ).EQ.ZERO ) THEN
488 * Form C = T22 - lambda*I in WORK(2:N,2:N).
491 WORK( I, I ) = WORK( I, I ) - WORK( 1, 1 )
497 * Triangularize the 2 by 2 block by unitary
498 * transformation U = [ cs i*ss ]
500 * such that the (1,1) position of WORK is complex
501 * eigenvalue lambda with positive imaginary part. (2,2)
502 * position of WORK is the complex eigenvalue lambda
503 * with negative imaginary part.
505 MU = SQRT( ABS( WORK( 1, 2 ) ) )*
506 $ SQRT( ABS( WORK( 2, 1 ) ) )
507 DELTA = DLAPY2( MU, WORK( 2, 1 ) )
509 SN = -WORK( 2, 1 ) / DELTA
513 * C**T = WORK(2:N,2:N) + i*[rwork(1) ..... rwork(n-1) ]
518 * where C**T is transpose of matrix C,
519 * and RWORK is stored starting in the N+1-st column of
523 WORK( 2, J ) = CS*WORK( 2, J )
524 WORK( J, J ) = WORK( J, J ) - WORK( 1, 1 )
528 WORK( 1, N+1 ) = TWO*MU
530 WORK( I, N+1 ) = SN*WORK( 1, I+1 )
536 * Estimate norm(inv(C**T))
541 CALL DLACN2( NN, WORK( 1, N+2 ), WORK( 1, N+4 ), IWORK,
547 * Real eigenvalue: solve C**T*x = scale*c.
549 CALL DLAQTR( .TRUE., .TRUE., N-1, WORK( 2, 2 ),
550 $ LDWORK, DUMMY, DUMM, SCALE,
551 $ WORK( 1, N+4 ), WORK( 1, N+6 ),
555 * Complex eigenvalue: solve
556 * C**T*(p+iq) = scale*(c+id) in real arithmetic.
558 CALL DLAQTR( .TRUE., .FALSE., N-1, WORK( 2, 2 ),
559 $ LDWORK, WORK( 1, N+1 ), MU, SCALE,
560 $ WORK( 1, N+4 ), WORK( 1, N+6 ),
566 * Real eigenvalue: solve C*x = scale*c.
568 CALL DLAQTR( .FALSE., .TRUE., N-1, WORK( 2, 2 ),
569 $ LDWORK, DUMMY, DUMM, SCALE,
570 $ WORK( 1, N+4 ), WORK( 1, N+6 ),
574 * Complex eigenvalue: solve
575 * C*(p+iq) = scale*(c+id) in real arithmetic.
577 CALL DLAQTR( .FALSE., .FALSE., N-1,
578 $ WORK( 2, 2 ), LDWORK,
579 $ WORK( 1, N+1 ), MU, SCALE,
580 $ WORK( 1, N+4 ), WORK( 1, N+6 ),
590 SEP( KS ) = SCALE / MAX( EST, SMLNUM )
592 $ SEP( KS+1 ) = SEP( KS )