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 stgevc(SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL, LDVL, VR, LDVR, MM, M, WORK, INFO)
STGEVC
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine sorgqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
SORGQR
subroutine sggbak(JOB, SIDE, N, ILO, IHI, LSCALE, RSCALE, M, V, LDV, INFO)
SGGBAK
subroutine sgghd3(COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q, LDQ, Z, LDZ, WORK, LWORK, INFO)
SGGHD3
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 slabad(SMALL, LARGE)
SLABAD
subroutine sormqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
SORMQR
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...
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 sggbal(JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE, RSCALE, WORK, INFO)
SGGBAL
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 sgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
SGEQRF
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.