LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
sggevx.f
Go to the documentation of this file.
1*> \brief <b> SGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices</b>
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download SGGEVX + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/sggevx.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/sggevx.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/sggevx.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE SGGEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, B, LDB,
20* ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, ILO,
21* IHI, LSCALE, RSCALE, ABNRM, BBNRM, RCONDE,
22* RCONDV, WORK, LWORK, IWORK, BWORK, INFO )
23*
24* .. Scalar Arguments ..
25* CHARACTER BALANC, JOBVL, JOBVR, SENSE
26* INTEGER IHI, ILO, INFO, LDA, LDB, LDVL, LDVR, LWORK, N
27* REAL ABNRM, BBNRM
28* ..
29* .. Array Arguments ..
30* LOGICAL BWORK( * )
31* INTEGER IWORK( * )
32* REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
33* $ B( LDB, * ), BETA( * ), LSCALE( * ),
34* $ RCONDE( * ), RCONDV( * ), RSCALE( * ),
35* $ VL( LDVL, * ), VR( LDVR, * ), WORK( * )
36* ..
37*
38*
39*> \par Purpose:
40* =============
41*>
42*> \verbatim
43*>
44*> SGGEVX computes for a pair of N-by-N real nonsymmetric matrices (A,B)
45*> the generalized eigenvalues, and optionally, the left and/or right
46*> generalized eigenvectors.
47*>
48*> Optionally also, it computes a balancing transformation to improve
49*> the conditioning of the eigenvalues and eigenvectors (ILO, IHI,
50*> LSCALE, RSCALE, ABNRM, and BBNRM), reciprocal condition numbers for
51*> the eigenvalues (RCONDE), and reciprocal condition numbers for the
52*> right eigenvectors (RCONDV).
53*>
54*> A generalized eigenvalue for a pair of matrices (A,B) is a scalar
55*> lambda or a ratio alpha/beta = lambda, such that A - lambda*B is
56*> singular. It is usually represented as the pair (alpha,beta), as
57*> there is a reasonable interpretation for beta=0, and even for both
58*> being zero.
59*>
60*> The right eigenvector v(j) corresponding to the eigenvalue lambda(j)
61*> of (A,B) satisfies
62*>
63*> A * v(j) = lambda(j) * B * v(j) .
64*>
65*> The left eigenvector u(j) corresponding to the eigenvalue lambda(j)
66*> of (A,B) satisfies
67*>
68*> u(j)**H * A = lambda(j) * u(j)**H * B.
69*>
70*> where u(j)**H is the conjugate-transpose of u(j).
71*>
72*> \endverbatim
73*
74* Arguments:
75* ==========
76*
77*> \param[in] BALANC
78*> \verbatim
79*> BALANC is CHARACTER*1
80*> Specifies the balance option to be performed.
81*> = 'N': do not diagonally scale or permute;
82*> = 'P': permute only;
83*> = 'S': scale only;
84*> = 'B': both permute and scale.
85*> Computed reciprocal condition numbers will be for the
86*> matrices after permuting and/or balancing. Permuting does
87*> not change condition numbers (in exact arithmetic), but
88*> balancing does.
89*> \endverbatim
90*>
91*> \param[in] JOBVL
92*> \verbatim
93*> JOBVL is CHARACTER*1
94*> = 'N': do not compute the left generalized eigenvectors;
95*> = 'V': compute the left generalized eigenvectors.
96*> \endverbatim
97*>
98*> \param[in] JOBVR
99*> \verbatim
100*> JOBVR is CHARACTER*1
101*> = 'N': do not compute the right generalized eigenvectors;
102*> = 'V': compute the right generalized eigenvectors.
103*> \endverbatim
104*>
105*> \param[in] SENSE
106*> \verbatim
107*> SENSE is CHARACTER*1
108*> Determines which reciprocal condition numbers are computed.
109*> = 'N': none are computed;
110*> = 'E': computed for eigenvalues only;
111*> = 'V': computed for eigenvectors only;
112*> = 'B': computed for eigenvalues and eigenvectors.
113*> \endverbatim
114*>
115*> \param[in] N
116*> \verbatim
117*> N is INTEGER
118*> The order of the matrices A, B, VL, and VR. N >= 0.
119*> \endverbatim
120*>
121*> \param[in,out] A
122*> \verbatim
123*> A is REAL array, dimension (LDA, N)
124*> On entry, the matrix A in the pair (A,B).
125*> On exit, A has been overwritten. If JOBVL='V' or JOBVR='V'
126*> or both, then A contains the first part of the real Schur
127*> form of the "balanced" versions of the input A and B.
128*> \endverbatim
129*>
130*> \param[in] LDA
131*> \verbatim
132*> LDA is INTEGER
133*> The leading dimension of A. LDA >= max(1,N).
134*> \endverbatim
135*>
136*> \param[in,out] B
137*> \verbatim
138*> B is REAL array, dimension (LDB, N)
139*> On entry, the matrix B in the pair (A,B).
140*> On exit, B has been overwritten. If JOBVL='V' or JOBVR='V'
141*> or both, then B contains the second part of the real Schur
142*> form of the "balanced" versions of the input A and B.
143*> \endverbatim
144*>
145*> \param[in] LDB
146*> \verbatim
147*> LDB is INTEGER
148*> The leading dimension of B. LDB >= max(1,N).
149*> \endverbatim
150*>
151*> \param[out] ALPHAR
152*> \verbatim
153*> ALPHAR is REAL array, dimension (N)
154*> \endverbatim
155*>
156*> \param[out] ALPHAI
157*> \verbatim
158*> ALPHAI is REAL array, dimension (N)
159*> \endverbatim
160*>
161*> \param[out] BETA
162*> \verbatim
163*> BETA is REAL array, dimension (N)
164*> On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will
165*> be the generalized eigenvalues. If ALPHAI(j) is zero, then
166*> the j-th eigenvalue is real; if positive, then the j-th and
167*> (j+1)-st eigenvalues are a complex conjugate pair, with
168*> ALPHAI(j+1) negative.
169*>
170*> Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)
171*> may easily over- or underflow, and BETA(j) may even be zero.
172*> Thus, the user should avoid naively computing the ratio
173*> ALPHA/BETA. However, ALPHAR and ALPHAI will be always less
174*> than and usually comparable with norm(A) in magnitude, and
175*> BETA always less than and usually comparable with norm(B).
176*> \endverbatim
177*>
178*> \param[out] VL
179*> \verbatim
180*> VL is REAL array, dimension (LDVL,N)
181*> If JOBVL = 'V', the left eigenvectors u(j) are stored one
182*> after another in the columns of VL, in the same order as
183*> their eigenvalues. If the j-th eigenvalue is real, then
184*> u(j) = VL(:,j), the j-th column of VL. If the j-th and
185*> (j+1)-th eigenvalues form a complex conjugate pair, then
186*> u(j) = VL(:,j)+i*VL(:,j+1) and u(j+1) = VL(:,j)-i*VL(:,j+1).
187*> Each eigenvector will be scaled so the largest component have
188*> abs(real part) + abs(imag. part) = 1.
189*> Not referenced if JOBVL = 'N'.
190*> \endverbatim
191*>
192*> \param[in] LDVL
193*> \verbatim
194*> LDVL is INTEGER
195*> The leading dimension of the matrix VL. LDVL >= 1, and
196*> if JOBVL = 'V', LDVL >= N.
197*> \endverbatim
198*>
199*> \param[out] VR
200*> \verbatim
201*> VR is REAL array, dimension (LDVR,N)
202*> If JOBVR = 'V', the right eigenvectors v(j) are stored one
203*> after another in the columns of VR, in the same order as
204*> their eigenvalues. If the j-th eigenvalue is real, then
205*> v(j) = VR(:,j), the j-th column of VR. If the j-th and
206*> (j+1)-th eigenvalues form a complex conjugate pair, then
207*> v(j) = VR(:,j)+i*VR(:,j+1) and v(j+1) = VR(:,j)-i*VR(:,j+1).
208*> Each eigenvector will be scaled so the largest component have
209*> abs(real part) + abs(imag. part) = 1.
210*> Not referenced if JOBVR = 'N'.
211*> \endverbatim
212*>
213*> \param[in] LDVR
214*> \verbatim
215*> LDVR is INTEGER
216*> The leading dimension of the matrix VR. LDVR >= 1, and
217*> if JOBVR = 'V', LDVR >= N.
218*> \endverbatim
219*>
220*> \param[out] ILO
221*> \verbatim
222*> ILO is INTEGER
223*> \endverbatim
224*>
225*> \param[out] IHI
226*> \verbatim
227*> IHI is INTEGER
228*> ILO and IHI are integer values such that on exit
229*> A(i,j) = 0 and B(i,j) = 0 if i > j and
230*> j = 1,...,ILO-1 or i = IHI+1,...,N.
231*> If BALANC = 'N' or 'S', ILO = 1 and IHI = N.
232*> \endverbatim
233*>
234*> \param[out] LSCALE
235*> \verbatim
236*> LSCALE is REAL array, dimension (N)
237*> Details of the permutations and scaling factors applied
238*> to the left side of A and B. If PL(j) is the index of the
239*> row interchanged with row j, and DL(j) is the scaling
240*> factor applied to row j, then
241*> LSCALE(j) = PL(j) for j = 1,...,ILO-1
242*> = DL(j) for j = ILO,...,IHI
243*> = PL(j) for j = IHI+1,...,N.
244*> The order in which the interchanges are made is N to IHI+1,
245*> then 1 to ILO-1.
246*> \endverbatim
247*>
248*> \param[out] RSCALE
249*> \verbatim
250*> RSCALE is REAL array, dimension (N)
251*> Details of the permutations and scaling factors applied
252*> to the right side of A and B. If PR(j) is the index of the
253*> column interchanged with column j, and DR(j) is the scaling
254*> factor applied to column j, then
255*> RSCALE(j) = PR(j) for j = 1,...,ILO-1
256*> = DR(j) for j = ILO,...,IHI
257*> = PR(j) for j = IHI+1,...,N
258*> The order in which the interchanges are made is N to IHI+1,
259*> then 1 to ILO-1.
260*> \endverbatim
261*>
262*> \param[out] ABNRM
263*> \verbatim
264*> ABNRM is REAL
265*> The one-norm of the balanced matrix A.
266*> \endverbatim
267*>
268*> \param[out] BBNRM
269*> \verbatim
270*> BBNRM is REAL
271*> The one-norm of the balanced matrix B.
272*> \endverbatim
273*>
274*> \param[out] RCONDE
275*> \verbatim
276*> RCONDE is REAL array, dimension (N)
277*> If SENSE = 'E' or 'B', the reciprocal condition numbers of
278*> the eigenvalues, stored in consecutive elements of the array.
279*> For a complex conjugate pair of eigenvalues two consecutive
280*> elements of RCONDE are set to the same value. Thus RCONDE(j),
281*> RCONDV(j), and the j-th columns of VL and VR all correspond
282*> to the j-th eigenpair.
283*> If SENSE = 'N' or 'V', RCONDE is not referenced.
284*> \endverbatim
285*>
286*> \param[out] RCONDV
287*> \verbatim
288*> RCONDV is REAL array, dimension (N)
289*> If SENSE = 'V' or 'B', the estimated reciprocal condition
290*> numbers of the eigenvectors, stored in consecutive elements
291*> of the array. For a complex eigenvector two consecutive
292*> elements of RCONDV are set to the same value. If the
293*> eigenvalues cannot be reordered to compute RCONDV(j),
294*> RCONDV(j) is set to 0; this can only occur when the true
295*> value would be very small anyway.
296*> If SENSE = 'N' or 'E', RCONDV is not referenced.
297*> \endverbatim
298*>
299*> \param[out] WORK
300*> \verbatim
301*> WORK is REAL array, dimension (MAX(1,LWORK))
302*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
303*> \endverbatim
304*>
305*> \param[in] LWORK
306*> \verbatim
307*> LWORK is INTEGER
308*> The dimension of the array WORK. LWORK >= max(1,2*N).
309*> If BALANC = 'S' or 'B', or JOBVL = 'V', or JOBVR = 'V',
310*> LWORK >= max(1,6*N).
311*> If SENSE = 'E', LWORK >= max(1,10*N).
312*> If SENSE = 'V' or 'B', LWORK >= 2*N*N+8*N+16.
313*>
314*> If LWORK = -1, then a workspace query is assumed; the routine
315*> only calculates the optimal size of the WORK array, returns
316*> this value as the first entry of the WORK array, and no error
317*> message related to LWORK is issued by XERBLA.
318*> \endverbatim
319*>
320*> \param[out] IWORK
321*> \verbatim
322*> IWORK is INTEGER array, dimension (N+6)
323*> If SENSE = 'E', IWORK is not referenced.
324*> \endverbatim
325*>
326*> \param[out] BWORK
327*> \verbatim
328*> BWORK is LOGICAL array, dimension (N)
329*> If SENSE = 'N', BWORK is not referenced.
330*> \endverbatim
331*>
332*> \param[out] INFO
333*> \verbatim
334*> INFO is INTEGER
335*> = 0: successful exit
336*> < 0: if INFO = -i, the i-th argument had an illegal value.
337*> = 1,...,N:
338*> The QZ iteration failed. No eigenvectors have been
339*> calculated, but ALPHAR(j), ALPHAI(j), and BETA(j)
340*> should be correct for j=INFO+1,...,N.
341*> > N: =N+1: other than QZ iteration failed in SHGEQZ.
342*> =N+2: error return from STGEVC.
343*> \endverbatim
344*
345* Authors:
346* ========
347*
348*> \author Univ. of Tennessee
349*> \author Univ. of California Berkeley
350*> \author Univ. of Colorado Denver
351*> \author NAG Ltd.
352*
353*> \ingroup ggevx
354*
355*> \par Further Details:
356* =====================
357*>
358*> \verbatim
359*>
360*> Balancing a matrix pair (A,B) includes, first, permuting rows and
361*> columns to isolate eigenvalues, second, applying diagonal similarity
362*> transformation to the rows and columns to make the rows and columns
363*> as close in norm as possible. The computed reciprocal condition
364*> numbers correspond to the balanced matrix. Permuting rows and columns
365*> will not change the condition numbers (in exact arithmetic) but
366*> diagonal scaling will. For further explanation of balancing, see
367*> section 4.11.1.2 of LAPACK Users' Guide.
368*>
369*> An approximate error bound on the chordal distance between the i-th
370*> computed generalized eigenvalue w and the corresponding exact
371*> eigenvalue lambda is
372*>
373*> chord(w, lambda) <= EPS * norm(ABNRM, BBNRM) / RCONDE(I)
374*>
375*> An approximate error bound for the angle between the i-th computed
376*> eigenvector VL(i) or VR(i) is given by
377*>
378*> EPS * norm(ABNRM, BBNRM) / DIF(i).
379*>
380*> For further explanation of the reciprocal condition numbers RCONDE
381*> and RCONDV, see section 4.11 of LAPACK User's Guide.
382*> \endverbatim
383*>
384* =====================================================================
385 SUBROUTINE sggevx( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, B,
386 $ LDB,
387 $ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, ILO,
388 $ IHI, LSCALE, RSCALE, ABNRM, BBNRM, RCONDE,
389 $ RCONDV, WORK, LWORK, IWORK, BWORK, INFO )
390*
391* -- LAPACK driver routine --
392* -- LAPACK is a software package provided by Univ. of Tennessee, --
393* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
394*
395* .. Scalar Arguments ..
396 CHARACTER BALANC, JOBVL, JOBVR, SENSE
397 INTEGER IHI, ILO, INFO, LDA, LDB, LDVL, LDVR, LWORK, N
398 REAL ABNRM, BBNRM
399* ..
400* .. Array Arguments ..
401 LOGICAL BWORK( * )
402 INTEGER IWORK( * )
403 REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
404 $ B( LDB, * ), BETA( * ), LSCALE( * ),
405 $ rconde( * ), rcondv( * ), rscale( * ),
406 $ vl( ldvl, * ), vr( ldvr, * ), work( * )
407* ..
408*
409* =====================================================================
410*
411* .. Parameters ..
412 REAL ZERO, ONE
413 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
414* ..
415* .. Local Scalars ..
416 LOGICAL ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY, NOSCL,
417 $ pair, wantsb, wantse, wantsn, wantsv
418 CHARACTER CHTEMP
419 INTEGER I, ICOLS, IERR, IJOBVL, IJOBVR, IN, IROWS,
420 $ itau, iwrk, iwrk1, j, jc, jr, m, maxwrk,
421 $ minwrk, mm
422 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
423 $ smlnum, temp
424* ..
425* .. Local Arrays ..
426 LOGICAL LDUMMA( 1 )
427* ..
428* .. External Subroutines ..
429 EXTERNAL SGEQRF, SGGBAK, SGGBAL, SGGHRD, SHGEQZ,
430 $ slacpy,
432 $ xerbla
433* ..
434* .. External Functions ..
435 LOGICAL LSAME
436 INTEGER ILAENV
437 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
438 EXTERNAL LSAME, ILAENV, SLAMCH,
439 $ slange, sroundup_lwork
440* ..
441* .. Intrinsic Functions ..
442 INTRINSIC abs, max, sqrt
443* ..
444* .. Executable Statements ..
445*
446* Decode the input arguments
447*
448 IF( lsame( jobvl, 'N' ) ) THEN
449 ijobvl = 1
450 ilvl = .false.
451 ELSE IF( lsame( jobvl, 'V' ) ) THEN
452 ijobvl = 2
453 ilvl = .true.
454 ELSE
455 ijobvl = -1
456 ilvl = .false.
457 END IF
458*
459 IF( lsame( jobvr, 'N' ) ) THEN
460 ijobvr = 1
461 ilvr = .false.
462 ELSE IF( lsame( jobvr, 'V' ) ) THEN
463 ijobvr = 2
464 ilvr = .true.
465 ELSE
466 ijobvr = -1
467 ilvr = .false.
468 END IF
469 ilv = ilvl .OR. ilvr
470*
471 noscl = lsame( balanc, 'N' ) .OR. lsame( balanc, 'P' )
472 wantsn = lsame( sense, 'N' )
473 wantse = lsame( sense, 'E' )
474 wantsv = lsame( sense, 'V' )
475 wantsb = lsame( sense, 'B' )
476*
477* Test the input arguments
478*
479 info = 0
480 lquery = ( lwork.EQ.-1 )
481 IF( .NOT.( noscl .OR. lsame( balanc, 'S' ) .OR.
482 $ lsame( balanc, 'B' ) ) ) THEN
483 info = -1
484 ELSE IF( ijobvl.LE.0 ) THEN
485 info = -2
486 ELSE IF( ijobvr.LE.0 ) THEN
487 info = -3
488 ELSE IF( .NOT.( wantsn .OR. wantse .OR. wantsb .OR. wantsv ) )
489 $ THEN
490 info = -4
491 ELSE IF( n.LT.0 ) THEN
492 info = -5
493 ELSE IF( lda.LT.max( 1, n ) ) THEN
494 info = -7
495 ELSE IF( ldb.LT.max( 1, n ) ) THEN
496 info = -9
497 ELSE IF( ldvl.LT.1 .OR. ( ilvl .AND. ldvl.LT.n ) ) THEN
498 info = -14
499 ELSE IF( ldvr.LT.1 .OR. ( ilvr .AND. ldvr.LT.n ) ) THEN
500 info = -16
501 END IF
502*
503* Compute workspace
504* (Note: Comments in the code beginning "Workspace:" describe the
505* minimal amount of workspace needed at that point in the code,
506* as well as the preferred amount for good performance.
507* NB refers to the optimal block size for the immediately
508* following subroutine, as returned by ILAENV. The workspace is
509* computed assuming ILO = 1 and IHI = N, the worst case.)
510*
511 IF( info.EQ.0 ) THEN
512 IF( n.EQ.0 ) THEN
513 minwrk = 1
514 maxwrk = 1
515 ELSE
516 IF( noscl .AND. .NOT.ilv ) THEN
517 minwrk = 2*n
518 ELSE
519 minwrk = 6*n
520 END IF
521 IF( wantse ) THEN
522 minwrk = 10*n
523 ELSE IF( wantsv .OR. wantsb ) THEN
524 minwrk = 2*n*( n + 4 ) + 16
525 END IF
526 maxwrk = minwrk
527 maxwrk = max( maxwrk,
528 $ n + n*ilaenv( 1, 'SGEQRF', ' ', n, 1, n,
529 $ 0 ) )
530 maxwrk = max( maxwrk,
531 $ n + n*ilaenv( 1, 'SORMQR', ' ', n, 1, n,
532 $ 0 ) )
533 IF( ilvl ) THEN
534 maxwrk = max( maxwrk, n +
535 $ n*ilaenv( 1, 'SORGQR', ' ', n, 1, n,
536 $ 0 ) )
537 END IF
538 END IF
539 work( 1 ) = sroundup_lwork(maxwrk)
540*
541 IF( lwork.LT.minwrk .AND. .NOT.lquery ) THEN
542 info = -26
543 END IF
544 END IF
545*
546 IF( info.NE.0 ) THEN
547 CALL xerbla( 'SGGEVX', -info )
548 RETURN
549 ELSE IF( lquery ) THEN
550 RETURN
551 END IF
552*
553* Quick return if possible
554*
555 IF( n.EQ.0 )
556 $ RETURN
557*
558*
559* Get machine constants
560*
561 eps = slamch( 'P' )
562 smlnum = slamch( 'S' )
563 bignum = one / smlnum
564 smlnum = sqrt( smlnum ) / eps
565 bignum = one / smlnum
566*
567* Scale A if max element outside range [SMLNUM,BIGNUM]
568*
569 anrm = slange( 'M', n, n, a, lda, work )
570 ilascl = .false.
571 IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
572 anrmto = smlnum
573 ilascl = .true.
574 ELSE IF( anrm.GT.bignum ) THEN
575 anrmto = bignum
576 ilascl = .true.
577 END IF
578 IF( ilascl )
579 $ CALL slascl( 'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
580*
581* Scale B if max element outside range [SMLNUM,BIGNUM]
582*
583 bnrm = slange( 'M', n, n, b, ldb, work )
584 ilbscl = .false.
585 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum ) THEN
586 bnrmto = smlnum
587 ilbscl = .true.
588 ELSE IF( bnrm.GT.bignum ) THEN
589 bnrmto = bignum
590 ilbscl = .true.
591 END IF
592 IF( ilbscl )
593 $ CALL slascl( 'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
594*
595* Permute and/or balance the matrix pair (A,B)
596* (Workspace: need 6*N if BALANC = 'S' or 'B', 1 otherwise)
597*
598 CALL sggbal( balanc, n, a, lda, b, ldb, ilo, ihi, lscale,
599 $ rscale,
600 $ work, ierr )
601*
602* Compute ABNRM and BBNRM
603*
604 abnrm = slange( '1', n, n, a, lda, work( 1 ) )
605 IF( ilascl ) THEN
606 work( 1 ) = abnrm
607 CALL slascl( 'G', 0, 0, anrmto, anrm, 1, 1, work( 1 ), 1,
608 $ ierr )
609 abnrm = work( 1 )
610 END IF
611*
612 bbnrm = slange( '1', n, n, b, ldb, work( 1 ) )
613 IF( ilbscl ) THEN
614 work( 1 ) = bbnrm
615 CALL slascl( 'G', 0, 0, bnrmto, bnrm, 1, 1, work( 1 ), 1,
616 $ ierr )
617 bbnrm = work( 1 )
618 END IF
619*
620* Reduce B to triangular form (QR decomposition of B)
621* (Workspace: need N, prefer N*NB )
622*
623 irows = ihi + 1 - ilo
624 IF( ilv .OR. .NOT.wantsn ) THEN
625 icols = n + 1 - ilo
626 ELSE
627 icols = irows
628 END IF
629 itau = 1
630 iwrk = itau + irows
631 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
632 $ work( iwrk ), lwork+1-iwrk, ierr )
633*
634* Apply the orthogonal transformation to A
635* (Workspace: need N, prefer N*NB)
636*
637 CALL sormqr( 'L', 'T', irows, icols, irows, b( ilo, ilo ), ldb,
638 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
639 $ lwork+1-iwrk, ierr )
640*
641* Initialize VL and/or VR
642* (Workspace: need N, prefer N*NB)
643*
644 IF( ilvl ) THEN
645 CALL slaset( 'Full', n, n, zero, one, vl, ldvl )
646 IF( irows.GT.1 ) THEN
647 CALL slacpy( 'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
648 $ vl( ilo+1, ilo ), ldvl )
649 END IF
650 CALL sorgqr( irows, irows, irows, vl( ilo, ilo ), ldvl,
651 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
652 END IF
653*
654 IF( ilvr )
655 $ CALL slaset( 'Full', n, n, zero, one, vr, ldvr )
656*
657* Reduce to generalized Hessenberg form
658* (Workspace: none needed)
659*
660 IF( ilv .OR. .NOT.wantsn ) THEN
661*
662* Eigenvectors requested -- work on whole matrix.
663*
664 CALL sgghrd( jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb, vl,
665 $ ldvl, vr, ldvr, ierr )
666 ELSE
667 CALL sgghrd( 'N', 'N', irows, 1, irows, a( ilo, ilo ), lda,
668 $ b( ilo, ilo ), ldb, vl, ldvl, vr, ldvr, ierr )
669 END IF
670*
671* Perform QZ algorithm (Compute eigenvalues, and optionally, the
672* Schur forms and Schur vectors)
673* (Workspace: need N)
674*
675 IF( ilv .OR. .NOT.wantsn ) THEN
676 chtemp = 'S'
677 ELSE
678 chtemp = 'E'
679 END IF
680*
681 CALL shgeqz( chtemp, jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb,
682 $ alphar, alphai, beta, vl, ldvl, vr, ldvr, work,
683 $ lwork, ierr )
684 IF( ierr.NE.0 ) THEN
685 IF( ierr.GT.0 .AND. ierr.LE.n ) THEN
686 info = ierr
687 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n ) THEN
688 info = ierr - n
689 ELSE
690 info = n + 1
691 END IF
692 GO TO 130
693 END IF
694*
695* Compute Eigenvectors and estimate condition numbers if desired
696* (Workspace: STGEVC: need 6*N
697* STGSNA: need 2*N*(N+2)+16 if SENSE = 'V' or 'B',
698* need N otherwise )
699*
700 IF( ilv .OR. .NOT.wantsn ) THEN
701 IF( ilv ) THEN
702 IF( ilvl ) THEN
703 IF( ilvr ) THEN
704 chtemp = 'B'
705 ELSE
706 chtemp = 'L'
707 END IF
708 ELSE
709 chtemp = 'R'
710 END IF
711*
712 CALL stgevc( chtemp, 'B', ldumma, n, a, lda, b, ldb, vl,
713 $ ldvl, vr, ldvr, n, in, work, ierr )
714 IF( ierr.NE.0 ) THEN
715 info = n + 2
716 GO TO 130
717 END IF
718 END IF
719*
720 IF( .NOT.wantsn ) THEN
721*
722* compute eigenvectors (STGEVC) and estimate condition
723* numbers (STGSNA). Note that the definition of the condition
724* number is not invariant under transformation (u,v) to
725* (Q*u, Z*v), where (u,v) are eigenvectors of the generalized
726* Schur form (S,T), Q and Z are orthogonal matrices. In order
727* to avoid using extra 2*N*N workspace, we have to recalculate
728* eigenvectors and estimate one condition numbers at a time.
729*
730 pair = .false.
731 DO 20 i = 1, n
732*
733 IF( pair ) THEN
734 pair = .false.
735 GO TO 20
736 END IF
737 mm = 1
738 IF( i.LT.n ) THEN
739 IF( a( i+1, i ).NE.zero ) THEN
740 pair = .true.
741 mm = 2
742 END IF
743 END IF
744*
745 DO 10 j = 1, n
746 bwork( j ) = .false.
747 10 CONTINUE
748 IF( mm.EQ.1 ) THEN
749 bwork( i ) = .true.
750 ELSE IF( mm.EQ.2 ) THEN
751 bwork( i ) = .true.
752 bwork( i+1 ) = .true.
753 END IF
754*
755 iwrk = mm*n + 1
756 iwrk1 = iwrk + mm*n
757*
758* Compute a pair of left and right eigenvectors.
759* (compute workspace: need up to 4*N + 6*N)
760*
761 IF( wantse .OR. wantsb ) THEN
762 CALL stgevc( 'B', 'S', bwork, n, a, lda, b, ldb,
763 $ work( 1 ), n, work( iwrk ), n, mm, m,
764 $ work( iwrk1 ), ierr )
765 IF( ierr.NE.0 ) THEN
766 info = n + 2
767 GO TO 130
768 END IF
769 END IF
770*
771 CALL stgsna( sense, 'S', bwork, n, a, lda, b, ldb,
772 $ work( 1 ), n, work( iwrk ), n, rconde( i ),
773 $ rcondv( i ), mm, m, work( iwrk1 ),
774 $ lwork-iwrk1+1, iwork, ierr )
775*
776 20 CONTINUE
777 END IF
778 END IF
779*
780* Undo balancing on VL and VR and normalization
781* (Workspace: none needed)
782*
783 IF( ilvl ) THEN
784 CALL sggbak( balanc, 'L', n, ilo, ihi, lscale, rscale, n,
785 $ vl,
786 $ ldvl, ierr )
787*
788 DO 70 jc = 1, n
789 IF( alphai( jc ).LT.zero )
790 $ GO TO 70
791 temp = zero
792 IF( alphai( jc ).EQ.zero ) THEN
793 DO 30 jr = 1, n
794 temp = max( temp, abs( vl( jr, jc ) ) )
795 30 CONTINUE
796 ELSE
797 DO 40 jr = 1, n
798 temp = max( temp, abs( vl( jr, jc ) )+
799 $ abs( vl( jr, jc+1 ) ) )
800 40 CONTINUE
801 END IF
802 IF( temp.LT.smlnum )
803 $ GO TO 70
804 temp = one / temp
805 IF( alphai( jc ).EQ.zero ) THEN
806 DO 50 jr = 1, n
807 vl( jr, jc ) = vl( jr, jc )*temp
808 50 CONTINUE
809 ELSE
810 DO 60 jr = 1, n
811 vl( jr, jc ) = vl( jr, jc )*temp
812 vl( jr, jc+1 ) = vl( jr, jc+1 )*temp
813 60 CONTINUE
814 END IF
815 70 CONTINUE
816 END IF
817 IF( ilvr ) THEN
818 CALL sggbak( balanc, 'R', n, ilo, ihi, lscale, rscale, n,
819 $ vr,
820 $ ldvr, ierr )
821 DO 120 jc = 1, n
822 IF( alphai( jc ).LT.zero )
823 $ GO TO 120
824 temp = zero
825 IF( alphai( jc ).EQ.zero ) THEN
826 DO 80 jr = 1, n
827 temp = max( temp, abs( vr( jr, jc ) ) )
828 80 CONTINUE
829 ELSE
830 DO 90 jr = 1, n
831 temp = max( temp, abs( vr( jr, jc ) )+
832 $ abs( vr( jr, jc+1 ) ) )
833 90 CONTINUE
834 END IF
835 IF( temp.LT.smlnum )
836 $ GO TO 120
837 temp = one / temp
838 IF( alphai( jc ).EQ.zero ) THEN
839 DO 100 jr = 1, n
840 vr( jr, jc ) = vr( jr, jc )*temp
841 100 CONTINUE
842 ELSE
843 DO 110 jr = 1, n
844 vr( jr, jc ) = vr( jr, jc )*temp
845 vr( jr, jc+1 ) = vr( jr, jc+1 )*temp
846 110 CONTINUE
847 END IF
848 120 CONTINUE
849 END IF
850*
851* Undo scaling if necessary
852*
853 130 CONTINUE
854*
855 IF( ilascl ) THEN
856 CALL slascl( 'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
857 $ ierr )
858 CALL slascl( 'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
859 $ ierr )
860 END IF
861*
862 IF( ilbscl ) THEN
863 CALL slascl( 'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
864 END IF
865*
866 work( 1 ) = sroundup_lwork(maxwrk)
867 RETURN
868*
869* End of SGGEVX
870*
871 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine sggevx(balanc, jobvl, jobvr, sense, n, a, lda, b, ldb, alphar, alphai, beta, vl, ldvl, vr, ldvr, ilo, ihi, lscale, rscale, abnrm, bbnrm, rconde, rcondv, work, lwork, iwork, bwork, info)
SGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices
Definition sggevx.f:390
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
Definition slacpy.f:101
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
Definition slascl.f:142
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition slaset.f:108
subroutine stgevc(side, howmny, select, n, s, lds, p, ldp, vl, ldvl, vr, ldvr, mm, m, work, info)
STGEVC
Definition stgevc.f:293
subroutine stgsna(job, howmny, select, n, a, lda, b, ldb, vl, ldvl, vr, ldvr, s, dif, mm, m, work, lwork, iwork, info)
STGSNA
Definition stgsna.f:379
subroutine sorgqr(m, n, k, a, lda, tau, work, lwork, info)
SORGQR
Definition sorgqr.f:126
subroutine sormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
SORMQR
Definition sormqr.f:166