223 SUBROUTINE sggev3( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR,
224 $ ALPHAI, BETA, VL, LDVL, VR, LDVR, WORK, LWORK,
232 CHARACTER JOBVL, JOBVR
233 INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, N
236 REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
237 $ B( LDB, * ), BETA( * ), VL( LDVL, * ),
238 $ vr( ldvr, * ), work( * )
245 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
248 LOGICAL ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY
250 INTEGER ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT, ILO,
251 $ in, iright, irows, itau, iwrk, jc, jr, lwkopt
252 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
266 EXTERNAL lsame, slamch, slange
269 INTRINSIC abs, max, sqrt
275 IF( lsame( jobvl,
'N' ) )
THEN
278 ELSE IF( lsame( jobvl,
'V' ) )
THEN
286 IF( lsame( jobvr,
'N' ) )
THEN
289 ELSE IF( lsame( jobvr,
'V' ) )
THEN
301 lquery = ( lwork.EQ.-1 )
302 IF( ijobvl.LE.0 )
THEN
304 ELSE IF( ijobvr.LE.0 )
THEN
306 ELSE IF( n.LT.0 )
THEN
308 ELSE IF( lda.LT.max( 1, n ) )
THEN
310 ELSE IF( ldb.LT.max( 1, n ) )
THEN
312 ELSE IF( ldvl.LT.1 .OR. ( ilvl .AND. ldvl.LT.n ) )
THEN
314 ELSE IF( ldvr.LT.1 .OR. ( ilvr .AND. ldvr.LT.n ) )
THEN
316 ELSE IF( lwork.LT.max( 1, 8*n ) .AND. .NOT.lquery )
THEN
323 CALL sgeqrf( n, n, b, ldb, work, work, -1, ierr )
324 lwkopt = max( 1, 8*n, 3*n+int( work( 1 ) ) )
325 CALL sormqr(
'L',
'T', n, n, n, b, ldb, work, a, lda, work,
327 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
328 CALL sgghd3( jobvl, jobvr, n, 1, n, a, lda, b, ldb, vl, ldvl,
329 $ vr, ldvr, work, -1, ierr )
330 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
332 CALL sorgqr( n, n, n, vl, ldvl, work, work, -1, ierr )
333 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
334 CALL slaqz0(
'S', jobvl, jobvr, n, 1, n, a, lda, b, ldb,
335 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
336 $ work, -1, 0, ierr )
337 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
339 CALL slaqz0(
'E', jobvl, jobvr, n, 1, n, a, lda, b, ldb,
340 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
341 $ work, -1, 0, ierr )
342 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
344 work( 1 ) = real( lwkopt )
349 CALL xerbla(
'SGGEV3 ', -info )
351 ELSE IF( lquery )
THEN
363 smlnum = slamch(
'S' )
364 bignum = one / smlnum
365 CALL slabad( smlnum, bignum )
366 smlnum = sqrt( smlnum ) / eps
367 bignum = one / smlnum
371 anrm = slange(
'M', n, n, a, lda, work )
373 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
376 ELSE IF( anrm.GT.bignum )
THEN
381 $
CALL slascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
385 bnrm = slange(
'M', n, n, b, ldb, work )
387 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
390 ELSE IF( bnrm.GT.bignum )
THEN
395 $
CALL slascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
402 CALL sggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
403 $ work( iright ), work( iwrk ), ierr )
407 irows = ihi + 1 - ilo
415 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
416 $ work( iwrk ), lwork+1-iwrk, ierr )
420 CALL sormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
421 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
422 $ lwork+1-iwrk, ierr )
427 CALL slaset(
'Full', n, n, zero, one, vl, ldvl )
428 IF( irows.GT.1 )
THEN
429 CALL slacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
430 $ vl( ilo+1, ilo ), ldvl )
432 CALL sorgqr( irows, irows, irows, vl( ilo, ilo ), ldvl,
433 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
439 $
CALL slaset(
'Full', n, n, zero, one, vr, ldvr )
447 CALL sgghd3( jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb, vl,
448 $ ldvl, vr, ldvr, work( iwrk ), lwork+1-iwrk, ierr )
450 CALL sgghd3(
'N',
'N', irows, 1, irows, a( ilo, ilo ), lda,
451 $ b( ilo, ilo ), ldb, vl, ldvl, vr, ldvr,
452 $ work( iwrk ), lwork+1-iwrk, ierr )
464 CALL slaqz0( chtemp, jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb,
465 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
466 $ work( iwrk ), lwork+1-iwrk, 0, ierr )
468 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
470 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
490 CALL stgevc( chtemp,
'B', ldumma, n, a, lda, b, ldb, vl, ldvl,
491 $ vr, ldvr, n, in, work( iwrk ), ierr )
500 CALL sggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
501 $ work( iright ), n, vl, ldvl, ierr )
503 IF( alphai( jc ).LT.zero )
506 IF( alphai( jc ).EQ.zero )
THEN
508 temp = max( temp, abs( vl( jr, jc ) ) )
512 temp = max( temp, abs( vl( jr, jc ) )+
513 $ abs( vl( jr, jc+1 ) ) )
519 IF( alphai( jc ).EQ.zero )
THEN
521 vl( jr, jc ) = vl( jr, jc )*temp
525 vl( jr, jc ) = vl( jr, jc )*temp
526 vl( jr, jc+1 ) = vl( jr, jc+1 )*temp
532 CALL sggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
533 $ work( iright ), n, vr, ldvr, ierr )
535 IF( alphai( jc ).LT.zero )
538 IF( alphai( jc ).EQ.zero )
THEN
540 temp = max( temp, abs( vr( jr, jc ) ) )
544 temp = max( temp, abs( vr( jr, jc ) )+
545 $ abs( vr( jr, jc+1 ) ) )
551 IF( alphai( jc ).EQ.zero )
THEN
553 vr( jr, jc ) = vr( jr, jc )*temp
557 vr( jr, jc ) = vr( jr, jc )*temp
558 vr( jr, jc+1 ) = vr( jr, jc+1 )*temp
573 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
574 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
578 CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
581 work( 1 ) = real( lwkopt )
subroutine slabad(SMALL, LARGE)
SLABAD
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.
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.
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
subroutine xerbla(SRNAME, INFO)
XERBLA
recursive subroutine slaqz0(WANTS, WANTQ, WANTZ, N, ILO, IHI, A, LDA, B, LDB, ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK, LWORK, REC, INFO)
SLAQZ0
subroutine sggbak(JOB, SIDE, N, ILO, IHI, LSCALE, RSCALE, M, V, LDV, INFO)
SGGBAK
subroutine sggbal(JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE, RSCALE, WORK, INFO)
SGGBAL
subroutine stgevc(SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL, LDVL, VR, LDVR, MM, M, WORK, INFO)
STGEVC
subroutine sgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
SGEQRF
subroutine sggev3(JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO)
SGGEV3 computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices (...
subroutine sorgqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
SORGQR
subroutine sormqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
SORMQR
subroutine sgghd3(COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q, LDQ, Z, LDZ, WORK, LWORK, INFO)
SGGHD3