3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download DTGSNA + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtgsna.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtgsna.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtgsna.f">
21 * SUBROUTINE DTGSNA( JOB, HOWMNY, SELECT, N, A, LDA, B, LDB, VL,
22 * LDVL, VR, LDVR, S, DIF, MM, M, WORK, LWORK,
25 * .. Scalar Arguments ..
26 * CHARACTER HOWMNY, JOB
27 * INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, M, MM, N
29 * .. Array Arguments ..
32 * DOUBLE PRECISION A( LDA, * ), B( LDB, * ), DIF( * ), S( * ),
33 * $ VL( LDVL, * ), VR( LDVR, * ), WORK( * )
42 *> DTGSNA estimates reciprocal condition numbers for specified
43 *> eigenvalues and/or eigenvectors of a matrix pair (A, B) in
44 *> generalized real Schur canonical form (or of any matrix pair
45 *> (Q*A*Z**T, Q*B*Z**T) with orthogonal matrices Q and Z, where
46 *> Z**T denotes the transpose of Z.
48 *> (A, B) must be in generalized real Schur form (as returned by DGGES),
49 *> i.e. A is block upper triangular with 1-by-1 and 2-by-2 diagonal
50 *> blocks. B is upper triangular.
60 *> Specifies whether condition numbers are required for
61 *> eigenvalues (S) or eigenvectors (DIF):
62 *> = 'E': for eigenvalues only (S);
63 *> = 'V': for eigenvectors only (DIF);
64 *> = 'B': for both eigenvalues and eigenvectors (S and DIF).
69 *> HOWMNY is CHARACTER*1
70 *> = 'A': compute condition numbers for all eigenpairs;
71 *> = 'S': compute condition numbers for selected eigenpairs
72 *> specified by the array SELECT.
77 *> SELECT is LOGICAL array, dimension (N)
78 *> If HOWMNY = 'S', SELECT specifies the eigenpairs for which
79 *> condition numbers are required. To select condition numbers
80 *> for the eigenpair corresponding to a real eigenvalue w(j),
81 *> SELECT(j) must be set to .TRUE.. To select condition numbers
82 *> corresponding to a complex conjugate pair of eigenvalues w(j)
83 *> and w(j+1), either SELECT(j) or SELECT(j+1) or both, must be
85 *> If HOWMNY = 'A', SELECT is not referenced.
91 *> The order of the square matrix pair (A, B). N >= 0.
96 *> A is DOUBLE PRECISION array, dimension (LDA,N)
97 *> The upper quasi-triangular matrix A in the pair (A,B).
103 *> The leading dimension of the array A. LDA >= max(1,N).
108 *> B is DOUBLE PRECISION array, dimension (LDB,N)
109 *> The upper triangular matrix B in the pair (A,B).
115 *> The leading dimension of the array B. LDB >= max(1,N).
120 *> VL is DOUBLE PRECISION array, dimension (LDVL,M)
121 *> If JOB = 'E' or 'B', VL must contain left eigenvectors of
122 *> (A, B), corresponding to the eigenpairs specified by HOWMNY
123 *> and SELECT. The eigenvectors must be stored in consecutive
124 *> columns of VL, as returned by DTGEVC.
125 *> If JOB = 'V', VL is not referenced.
131 *> The leading dimension of the array VL. LDVL >= 1.
132 *> If JOB = 'E' or 'B', LDVL >= N.
137 *> VR is DOUBLE PRECISION array, dimension (LDVR,M)
138 *> If JOB = 'E' or 'B', VR must contain right eigenvectors of
139 *> (A, B), corresponding to the eigenpairs specified by HOWMNY
140 *> and SELECT. The eigenvectors must be stored in consecutive
141 *> columns ov VR, as returned by DTGEVC.
142 *> If JOB = 'V', VR is not referenced.
148 *> The leading dimension of the array VR. LDVR >= 1.
149 *> If JOB = 'E' or 'B', LDVR >= N.
154 *> S is DOUBLE PRECISION array, dimension (MM)
155 *> If JOB = 'E' or 'B', the reciprocal condition numbers of the
156 *> selected eigenvalues, stored in consecutive elements of the
157 *> array. For a complex conjugate pair of eigenvalues two
158 *> consecutive elements of S are set to the same value. Thus
159 *> S(j), DIF(j), and the j-th columns of VL and VR all
160 *> correspond to the same eigenpair (but not in general the
161 *> j-th eigenpair, unless all eigenpairs are selected).
162 *> If JOB = 'V', S is not referenced.
167 *> DIF is DOUBLE PRECISION array, dimension (MM)
168 *> If JOB = 'V' or 'B', the estimated reciprocal condition
169 *> numbers of the selected eigenvectors, stored in consecutive
170 *> elements of the array. For a complex eigenvector two
171 *> consecutive elements of DIF are set to the same value. If
172 *> the eigenvalues cannot be reordered to compute DIF(j), DIF(j)
173 *> is set to 0; this can only occur when the true value would be
174 *> very small anyway.
175 *> If JOB = 'E', DIF is not referenced.
181 *> The number of elements in the arrays S and DIF. MM >= M.
187 *> The number of elements of the arrays S and DIF used to store
188 *> the specified condition numbers; for each selected real
189 *> eigenvalue one element is used, and for each selected complex
190 *> conjugate pair of eigenvalues, two elements are used.
191 *> If HOWMNY = 'A', M is set to N.
196 *> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))
197 *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
203 *> The dimension of the array WORK. LWORK >= max(1,N).
204 *> If JOB = 'V' or 'B' LWORK >= 2*N*(N+2)+16.
206 *> If LWORK = -1, then a workspace query is assumed; the routine
207 *> only calculates the optimal size of the WORK array, returns
208 *> this value as the first entry of the WORK array, and no error
209 *> message related to LWORK is issued by XERBLA.
214 *> IWORK is INTEGER array, dimension (N + 6)
215 *> If JOB = 'E', IWORK is not referenced.
221 *> =0: Successful exit
222 *> <0: If INFO = -i, the i-th argument had an illegal value
228 *> \author Univ. of Tennessee
229 *> \author Univ. of California Berkeley
230 *> \author Univ. of Colorado Denver
233 *> \date November 2011
235 *> \ingroup doubleOTHERcomputational
237 *> \par Further Details:
238 * =====================
242 *> The reciprocal of the condition number of a generalized eigenvalue
243 *> w = (a, b) is defined as
245 *> S(w) = (|u**TAv|**2 + |u**TBv|**2)**(1/2) / (norm(u)*norm(v))
247 *> where u and v are the left and right eigenvectors of (A, B)
248 *> corresponding to w; |z| denotes the absolute value of the complex
249 *> number, and norm(u) denotes the 2-norm of the vector u.
250 *> The pair (a, b) corresponds to an eigenvalue w = a/b (= u**TAv/u**TBv)
251 *> of the matrix pair (A, B). If both a and b equal zero, then (A B) is
252 *> singular and S(I) = -1 is returned.
254 *> An approximate error bound on the chordal distance between the i-th
255 *> computed generalized eigenvalue w and the corresponding exact
256 *> eigenvalue lambda is
258 *> chord(w, lambda) <= EPS * norm(A, B) / S(I)
260 *> where EPS is the machine precision.
262 *> The reciprocal of the condition number DIF(i) of right eigenvector u
263 *> and left eigenvector v corresponding to the generalized eigenvalue w
264 *> is defined as follows:
266 *> a) If the i-th eigenvalue w = (a,b) is real
268 *> Suppose U and V are orthogonal transformations such that
270 *> U**T*(A, B)*V = (S, T) = ( a * ) ( b * ) 1
271 *> ( 0 S22 ),( 0 T22 ) n-1
274 *> Then the reciprocal condition number DIF(i) is
276 *> Difl((a, b), (S22, T22)) = sigma-min( Zl ),
278 *> where sigma-min(Zl) denotes the smallest singular value of the
279 *> 2(n-1)-by-2(n-1) matrix
281 *> Zl = [ kron(a, In-1) -kron(1, S22) ]
282 *> [ kron(b, In-1) -kron(1, T22) ] .
284 *> Here In-1 is the identity matrix of size n-1. kron(X, Y) is the
285 *> Kronecker product between the matrices X and Y.
287 *> Note that if the default method for computing DIF(i) is wanted
288 *> (see DLATDF), then the parameter DIFDRI (see below) should be
289 *> changed from 3 to 4 (routine DLATDF(IJOB = 2 will be used)).
290 *> See DTGSYL for more details.
292 *> b) If the i-th and (i+1)-th eigenvalues are complex conjugate pair,
294 *> Suppose U and V are orthogonal transformations such that
296 *> U**T*(A, B)*V = (S, T) = ( S11 * ) ( T11 * ) 2
297 *> ( 0 S22 ),( 0 T22) n-2
300 *> and (S11, T11) corresponds to the complex conjugate eigenvalue
301 *> pair (w, conjg(w)). There exist unitary matrices U1 and V1 such
304 *> U1**T*S11*V1 = ( s11 s12 ) and U1**T*T11*V1 = ( t11 t12 )
305 *> ( 0 s22 ) ( 0 t22 )
307 *> where the generalized eigenvalues w = s11/t11 and
308 *> conjg(w) = s22/t22.
310 *> Then the reciprocal condition number DIF(i) is bounded by
312 *> min( d1, max( 1, |real(s11)/real(s22)| )*d2 )
314 *> where, d1 = Difl((s11, t11), (s22, t22)) = sigma-min(Z1), where
315 *> Z1 is the complex 2-by-2 matrix
320 *> This is done by computing (using real arithmetic) the
321 *> roots of the characteristical polynomial det(Z1**T * Z1 - lambda I),
322 *> where Z1**T denotes the transpose of Z1 and det(X) denotes
323 *> the determinant of X.
325 *> and d2 is an upper bound on Difl((S11, T11), (S22, T22)), i.e. an
326 *> upper bound on sigma-min(Z2), where Z2 is (2n-2)-by-(2n-2)
328 *> Z2 = [ kron(S11**T, In-2) -kron(I2, S22) ]
329 *> [ kron(T11**T, In-2) -kron(I2, T22) ]
331 *> Note that if the default method for computing DIF is wanted (see
332 *> DLATDF), then the parameter DIFDRI (see below) should be changed
333 *> from 3 to 4 (routine DLATDF(IJOB = 2 will be used)). See DTGSYL
336 *> For each eigenvalue/vector specified by SELECT, DIF stores a
337 *> Frobenius norm-based estimate of Difl.
339 *> An approximate error bound for the i-th computed eigenvector VL(i) or
342 *> EPS * norm(A, B) / DIF(i).
344 *> See ref. [2-3] for more details and further references.
347 *> \par Contributors:
350 *> Bo Kagstrom and Peter Poromaa, Department of Computing Science,
351 *> Umea University, S-901 87 Umea, Sweden.
358 *> [1] B. Kagstrom; A Direct Method for Reordering Eigenvalues in the
359 *> Generalized Real Schur Form of a Regular Matrix Pair (A, B), in
360 *> M.S. Moonen et al (eds), Linear Algebra for Large Scale and
361 *> Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218.
363 *> [2] B. Kagstrom and P. Poromaa; Computing Eigenspaces with Specified
364 *> Eigenvalues of a Regular Matrix Pair (A, B) and Condition
365 *> Estimation: Theory, Algorithms and Software,
366 *> Report UMINF - 94.04, Department of Computing Science, Umea
367 *> University, S-901 87 Umea, Sweden, 1994. Also as LAPACK Working
368 *> Note 87. To appear in Numerical Algorithms, 1996.
370 *> [3] B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software
371 *> for Solving the Generalized Sylvester Equation and Estimating the
372 *> Separation between Regular Matrix Pairs, Report UMINF - 93.23,
373 *> Department of Computing Science, Umea University, S-901 87 Umea,
374 *> Sweden, December 1993, Revised April 1994, Also as LAPACK Working
375 *> Note 75. To appear in ACM Trans. on Math. Software, Vol 22,
379 * =====================================================================
380 SUBROUTINE DTGSNA( JOB, HOWMNY, SELECT, N, A, LDA, B, LDB, VL,
381 $ LDVL, VR, LDVR, S, DIF, MM, M, WORK, LWORK,
384 * -- LAPACK computational routine (version 3.4.0) --
385 * -- LAPACK is a software package provided by Univ. of Tennessee, --
386 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
389 * .. Scalar Arguments ..
390 CHARACTER HOWMNY, JOB
391 INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, M, MM, N
393 * .. Array Arguments ..
396 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), DIF( * ), S( * ),
397 $ VL( LDVL, * ), VR( LDVR, * ), WORK( * )
400 * =====================================================================
404 PARAMETER ( DIFDRI = 3 )
405 DOUBLE PRECISION ZERO, ONE, TWO, FOUR
406 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,
409 * .. Local Scalars ..
410 LOGICAL LQUERY, PAIR, SOMCON, WANTBH, WANTDF, WANTS
411 INTEGER I, IERR, IFST, ILST, IZ, K, KS, LWMIN, N1, N2
412 DOUBLE PRECISION ALPHAI, ALPHAR, ALPRQT, BETA, C1, C2, COND,
413 $ EPS, LNRM, RNRM, ROOT1, ROOT2, SCALE, SMLNUM,
414 $ TMPII, TMPIR, TMPRI, TMPRR, UHAV, UHAVI, UHBV,
418 DOUBLE PRECISION DUMMY( 1 ), DUMMY1( 1 )
420 * .. External Functions ..
422 DOUBLE PRECISION DDOT, DLAMCH, DLAPY2, DNRM2
423 EXTERNAL LSAME, DDOT, DLAMCH, DLAPY2, DNRM2
425 * .. External Subroutines ..
426 EXTERNAL DGEMV, DLACPY, DLAG2, DTGEXC, DTGSYL, XERBLA
428 * .. Intrinsic Functions ..
429 INTRINSIC MAX, MIN, SQRT
431 * .. Executable Statements ..
433 * Decode and test the input parameters
435 WANTBH = LSAME( JOB, 'B' )
436 WANTS = LSAME( JOB, 'E' ) .OR. WANTBH
437 WANTDF = LSAME( JOB, 'V' ) .OR. WANTBH
439 SOMCON = LSAME( HOWMNY, 'S' )
442 LQUERY = ( LWORK.EQ.-1 )
444 IF( .NOT.WANTS .AND. .NOT.WANTDF ) THEN
446 ELSE IF( .NOT.LSAME( HOWMNY, 'A' ) .AND. .NOT.SOMCON ) THEN
448 ELSE IF( N.LT.0 ) THEN
450 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
452 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
454 ELSE IF( WANTS .AND. LDVL.LT.N ) THEN
456 ELSE IF( WANTS .AND. LDVR.LT.N ) THEN
460 * Set M to the number of eigenpairs for which condition numbers
461 * are required, and test MM.
471 IF( A( K+1, K ).EQ.ZERO ) THEN
476 IF( SELECT( K ) .OR. SELECT( K+1 ) )
491 ELSE IF( LSAME( JOB, 'V' ) .OR. LSAME( JOB, 'B' ) ) THEN
492 LWMIN = 2*N*( N + 2 ) + 16
500 ELSE IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
506 CALL XERBLA( 'DTGSNA', -INFO )
508 ELSE IF( LQUERY ) THEN
512 * Quick return if possible
517 * Get machine constants
520 SMLNUM = DLAMCH( 'S' ) / EPS
526 * Determine whether A(k,k) begins a 1-by-1 or 2-by-2 block.
533 $ PAIR = A( K+1, K ).NE.ZERO
536 * Determine whether condition numbers are required for the k-th
541 IF( .NOT.SELECT( K ) .AND. .NOT.SELECT( K+1 ) )
544 IF( .NOT.SELECT( K ) )
553 * Compute the reciprocal condition number of the k-th
558 * Complex eigenvalue pair.
560 RNRM = DLAPY2( DNRM2( N, VR( 1, KS ), 1 ),
561 $ DNRM2( N, VR( 1, KS+1 ), 1 ) )
562 LNRM = DLAPY2( DNRM2( N, VL( 1, KS ), 1 ),
563 $ DNRM2( N, VL( 1, KS+1 ), 1 ) )
564 CALL DGEMV( 'N', N, N, ONE, A, LDA, VR( 1, KS ), 1, ZERO,
566 TMPRR = DDOT( N, WORK, 1, VL( 1, KS ), 1 )
567 TMPRI = DDOT( N, WORK, 1, VL( 1, KS+1 ), 1 )
568 CALL DGEMV( 'N', N, N, ONE, A, LDA, VR( 1, KS+1 ), 1,
570 TMPII = DDOT( N, WORK, 1, VL( 1, KS+1 ), 1 )
571 TMPIR = DDOT( N, WORK, 1, VL( 1, KS ), 1 )
573 UHAVI = TMPIR - TMPRI
574 CALL DGEMV( 'N', N, N, ONE, B, LDB, VR( 1, KS ), 1, ZERO,
576 TMPRR = DDOT( N, WORK, 1, VL( 1, KS ), 1 )
577 TMPRI = DDOT( N, WORK, 1, VL( 1, KS+1 ), 1 )
578 CALL DGEMV( 'N', N, N, ONE, B, LDB, VR( 1, KS+1 ), 1,
580 TMPII = DDOT( N, WORK, 1, VL( 1, KS+1 ), 1 )
581 TMPIR = DDOT( N, WORK, 1, VL( 1, KS ), 1 )
583 UHBVI = TMPIR - TMPRI
584 UHAV = DLAPY2( UHAV, UHAVI )
585 UHBV = DLAPY2( UHBV, UHBVI )
586 COND = DLAPY2( UHAV, UHBV )
587 S( KS ) = COND / ( RNRM*LNRM )
594 RNRM = DNRM2( N, VR( 1, KS ), 1 )
595 LNRM = DNRM2( N, VL( 1, KS ), 1 )
596 CALL DGEMV( 'N', N, N, ONE, A, LDA, VR( 1, KS ), 1, ZERO,
598 UHAV = DDOT( N, WORK, 1, VL( 1, KS ), 1 )
599 CALL DGEMV( 'N', N, N, ONE, B, LDB, VR( 1, KS ), 1, ZERO,
601 UHBV = DDOT( N, WORK, 1, VL( 1, KS ), 1 )
602 COND = DLAPY2( UHAV, UHBV )
603 IF( COND.EQ.ZERO ) THEN
606 S( KS ) = COND / ( RNRM*LNRM )
613 DIF( KS ) = DLAPY2( A( 1, 1 ), B( 1, 1 ) )
617 * Estimate the reciprocal condition number of the k-th
621 * Copy the 2-by 2 pencil beginning at (A(k,k), B(k, k)).
622 * Compute the eigenvalue(s) at position K.
624 WORK( 1 ) = A( K, K )
625 WORK( 2 ) = A( K+1, K )
626 WORK( 3 ) = A( K, K+1 )
627 WORK( 4 ) = A( K+1, K+1 )
628 WORK( 5 ) = B( K, K )
629 WORK( 6 ) = B( K+1, K )
630 WORK( 7 ) = B( K, K+1 )
631 WORK( 8 ) = B( K+1, K+1 )
632 CALL DLAG2( WORK, 2, WORK( 5 ), 2, SMLNUM*EPS, BETA,
633 $ DUMMY1( 1 ), ALPHAR, DUMMY( 1 ), ALPHAI )
635 C1 = TWO*( ALPHAR*ALPHAR+ALPHAI*ALPHAI+BETA*BETA )
636 C2 = FOUR*BETA*BETA*ALPHAI*ALPHAI
637 ROOT1 = C1 + SQRT( C1*C1-4.0D0*C2 )
640 COND = MIN( SQRT( ROOT1 ), SQRT( ROOT2 ) )
643 * Copy the matrix (A, B) to the array WORK and swap the
644 * diagonal block beginning at A(k,k) to the (1,1) position.
646 CALL DLACPY( 'Full', N, N, A, LDA, WORK, N )
647 CALL DLACPY( 'Full', N, N, B, LDB, WORK( N*N+1 ), N )
651 CALL DTGEXC( .FALSE., .FALSE., N, WORK, N, WORK( N*N+1 ), N,
652 $ DUMMY, 1, DUMMY1, 1, IFST, ILST,
653 $ WORK( N*N*2+1 ), LWORK-2*N*N, IERR )
657 * Ill-conditioned problem - swap rejected.
662 * Reordering successful, solve generalized Sylvester
663 * equation for R and L,
664 * A22 * R - L * A11 = A12
665 * B22 * R - L * B11 = B12,
666 * and compute estimate of Difl((A11,B11), (A22, B22)).
669 IF( WORK( 2 ).NE.ZERO )
677 CALL DTGSYL( 'N', DIFDRI, N2, N1, WORK( N*N1+N1+1 ),
678 $ N, WORK, N, WORK( N1+1 ), N,
679 $ WORK( N*N1+N1+I ), N, WORK( I ), N,
680 $ WORK( N1+I ), N, SCALE, DIF( KS ),
681 $ WORK( IZ+1 ), LWORK-2*N*N, IWORK, IERR )
684 $ DIF( KS ) = MIN( MAX( ONE, ALPRQT )*DIF( KS ),
689 $ DIF( KS+1 ) = DIF( KS )