303 SUBROUTINE sgeevx( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, WR, WI,
304 $ VL, LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM,
305 $ RCONDE, RCONDV, WORK, LWORK, IWORK, INFO )
313 CHARACTER BALANC, JOBVL, JOBVR, SENSE
314 INTEGER IHI, ILO, INFO, LDA, LDVL, LDVR, LWORK, N
319 REAL A( lda, * ), RCONDE( * ), RCONDV( * ),
320 $ scale( * ), vl( ldvl, * ), vr( ldvr, * ),
321 $ wi( * ), work( * ), wr( * )
328 parameter( zero = 0.0e0, one = 1.0e0 )
331 LOGICAL LQUERY, SCALEA, WANTVL, WANTVR, WNTSNB, WNTSNE,
334 INTEGER HSWORK, I, ICOND, IERR, ITAU, IWRK, K,
335 $ lwork_trevc, maxwrk, minwrk, nout
336 REAL ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
350 INTEGER ISAMAX, ILAENV
351 REAL SLAMCH, SLANGE, SLAPY2, SNRM2
352 EXTERNAL lsame, isamax, ilaenv, slamch, slange, slapy2,
363 lquery = ( lwork.EQ.-1 )
364 wantvl = lsame( jobvl,
'V' )
365 wantvr = lsame( jobvr,
'V' )
366 wntsnn = lsame( sense,
'N' )
367 wntsne = lsame( sense,
'E' )
368 wntsnv = lsame( sense,
'V' )
369 wntsnb = lsame( sense,
'B' )
370 IF( .NOT.( lsame( balanc,
'N' ) .OR. lsame( balanc,
'S' )
371 $ .OR. lsame( balanc,
'P' ) .OR. lsame( balanc,
'B' ) ) )
374 ELSE IF( ( .NOT.wantvl ) .AND. ( .NOT.lsame( jobvl,
'N' ) ) )
THEN 376 ELSE IF( ( .NOT.wantvr ) .AND. ( .NOT.lsame( jobvr,
'N' ) ) )
THEN 378 ELSE IF( .NOT.( wntsnn .OR. wntsne .OR. wntsnb .OR. wntsnv ) .OR.
379 $ ( ( wntsne .OR. wntsnb ) .AND. .NOT.( wantvl .AND.
382 ELSE IF( n.LT.0 )
THEN 384 ELSE IF( lda.LT.max( 1, n ) )
THEN 386 ELSE IF( ldvl.LT.1 .OR. ( wantvl .AND. ldvl.LT.n ) )
THEN 388 ELSE IF( ldvr.LT.1 .OR. ( wantvr .AND. ldvr.LT.n ) )
THEN 407 maxwrk = n + n*ilaenv( 1,
'SGEHRD',
' ', n, 1, n, 0 )
410 CALL strevc3(
'L',
'B',
SELECT, n, a, lda,
411 $ vl, ldvl, vr, ldvr,
412 $ n, nout, work, -1, ierr )
413 lwork_trevc = int( work(1) )
414 maxwrk = max( maxwrk, n + lwork_trevc )
415 CALL shseqr(
'S',
'V', n, 1, n, a, lda, wr, wi, vl, ldvl,
417 ELSE IF( wantvr )
THEN 418 CALL strevc3(
'R',
'B',
SELECT, n, a, lda,
419 $ vl, ldvl, vr, ldvr,
420 $ n, nout, work, -1, ierr )
421 lwork_trevc = int( work(1) )
422 maxwrk = max( maxwrk, n + lwork_trevc )
423 CALL shseqr(
'S',
'V', n, 1, n, a, lda, wr, wi, vr, ldvr,
427 CALL shseqr(
'E',
'N', n, 1, n, a, lda, wr, wi, vr,
428 $ ldvr, work, -1, info )
430 CALL shseqr(
'S',
'N', n, 1, n, a, lda, wr, wi, vr,
431 $ ldvr, work, -1, info )
434 hswork = int( work(1) )
436 IF( ( .NOT.wantvl ) .AND. ( .NOT.wantvr ) )
THEN 439 $ minwrk = max( minwrk, n*n+6*n )
440 maxwrk = max( maxwrk, hswork )
442 $ maxwrk = max( maxwrk, n*n + 6*n )
445 IF( ( .NOT.wntsnn ) .AND. ( .NOT.wntsne ) )
446 $ minwrk = max( minwrk, n*n + 6*n )
447 maxwrk = max( maxwrk, hswork )
448 maxwrk = max( maxwrk, n + ( n - 1 )*ilaenv( 1,
'SORGHR',
449 $
' ', n, 1, n, -1 ) )
450 IF( ( .NOT.wntsnn ) .AND. ( .NOT.wntsne ) )
451 $ maxwrk = max( maxwrk, n*n + 6*n )
452 maxwrk = max( maxwrk, 3*n )
454 maxwrk = max( maxwrk, minwrk )
458 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN 464 CALL xerbla(
'SGEEVX', -info )
466 ELSE IF( lquery )
THEN 478 smlnum = slamch(
'S' )
479 bignum = one / smlnum
480 CALL slabad( smlnum, bignum )
481 smlnum = sqrt( smlnum ) / eps
482 bignum = one / smlnum
487 anrm = slange(
'M', n, n, a, lda, dum )
489 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN 492 ELSE IF( anrm.GT.bignum )
THEN 497 $
CALL slascl(
'G', 0, 0, anrm, cscale, n, n, a, lda, ierr )
501 CALL sgebal( balanc, n, a, lda, ilo, ihi, scale, ierr )
502 abnrm = slange(
'1', n, n, a, lda, dum )
505 CALL slascl(
'G', 0, 0, cscale, anrm, 1, 1, dum, 1, ierr )
514 CALL sgehrd( n, ilo, ihi, a, lda, work( itau ), work( iwrk ),
515 $ lwork-iwrk+1, ierr )
523 CALL slacpy(
'L', n, n, a, lda, vl, ldvl )
528 CALL sorghr( n, ilo, ihi, vl, ldvl, work( itau ), work( iwrk ),
529 $ lwork-iwrk+1, ierr )
535 CALL shseqr(
'S',
'V', n, ilo, ihi, a, lda, wr, wi, vl, ldvl,
536 $ work( iwrk ), lwork-iwrk+1, info )
544 CALL slacpy(
'F', n, n, vl, ldvl, vr, ldvr )
547 ELSE IF( wantvr )
THEN 553 CALL slacpy(
'L', n, n, a, lda, vr, ldvr )
558 CALL sorghr( n, ilo, ihi, vr, ldvr, work( itau ), work( iwrk ),
559 $ lwork-iwrk+1, ierr )
565 CALL shseqr(
'S',
'V', n, ilo, ihi, a, lda, wr, wi, vr, ldvr,
566 $ work( iwrk ), lwork-iwrk+1, info )
582 CALL shseqr( job,
'N', n, ilo, ihi, a, lda, wr, wi, vr, ldvr,
583 $ work( iwrk ), lwork-iwrk+1, info )
591 IF( wantvl .OR. wantvr )
THEN 596 CALL strevc3( side,
'B',
SELECT, n, a, lda, vl, ldvl, vr, ldvr,
597 $ n, nout, work( iwrk ), lwork-iwrk+1, ierr )
603 IF( .NOT.wntsnn )
THEN 604 CALL strsna( sense,
'A',
SELECT, n, a, lda, vl, ldvl, vr, ldvr,
605 $ rconde, rcondv, n, nout, work( iwrk ), n, iwork,
613 CALL sgebak( balanc,
'L', n, ilo, ihi, scale, n, vl, ldvl,
619 IF( wi( i ).EQ.zero )
THEN 620 scl = one / snrm2( n, vl( 1, i ), 1 )
621 CALL sscal( n, scl, vl( 1, i ), 1 )
622 ELSE IF( wi( i ).GT.zero )
THEN 623 scl = one / slapy2( snrm2( n, vl( 1, i ), 1 ),
624 $ snrm2( n, vl( 1, i+1 ), 1 ) )
625 CALL sscal( n, scl, vl( 1, i ), 1 )
626 CALL sscal( n, scl, vl( 1, i+1 ), 1 )
628 work( k ) = vl( k, i )**2 + vl( k, i+1 )**2
630 k = isamax( n, work, 1 )
631 CALL slartg( vl( k, i ), vl( k, i+1 ), cs, sn, r )
632 CALL srot( n, vl( 1, i ), 1, vl( 1, i+1 ), 1, cs, sn )
642 CALL sgebak( balanc,
'R', n, ilo, ihi, scale, n, vr, ldvr,
648 IF( wi( i ).EQ.zero )
THEN 649 scl = one / snrm2( n, vr( 1, i ), 1 )
650 CALL sscal( n, scl, vr( 1, i ), 1 )
651 ELSE IF( wi( i ).GT.zero )
THEN 652 scl = one / slapy2( snrm2( n, vr( 1, i ), 1 ),
653 $ snrm2( n, vr( 1, i+1 ), 1 ) )
654 CALL sscal( n, scl, vr( 1, i ), 1 )
655 CALL sscal( n, scl, vr( 1, i+1 ), 1 )
657 work( k ) = vr( k, i )**2 + vr( k, i+1 )**2
659 k = isamax( n, work, 1 )
660 CALL slartg( vr( k, i ), vr( k, i+1 ), cs, sn, r )
661 CALL srot( n, vr( 1, i ), 1, vr( 1, i+1 ), 1, cs, sn )
671 CALL slascl(
'G', 0, 0, cscale, anrm, n-info, 1, wr( info+1 ),
672 $ max( n-info, 1 ), ierr )
673 CALL slascl(
'G', 0, 0, cscale, anrm, n-info, 1, wi( info+1 ),
674 $ max( n-info, 1 ), ierr )
676 IF( ( wntsnv .OR. wntsnb ) .AND. icond.EQ.0 )
677 $
CALL slascl(
'G', 0, 0, cscale, anrm, n, 1, rcondv, n,
680 CALL slascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, wr, n,
682 CALL slascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, wi, n,
subroutine sgebak(JOB, SIDE, N, ILO, IHI, SCALE, M, V, LDV, INFO)
SGEBAK
subroutine sgehrd(N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO)
SGEHRD
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine sgebal(JOB, N, A, LDA, ILO, IHI, SCALE, INFO)
SGEBAL
subroutine sorghr(N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO)
SORGHR
subroutine strevc3(SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, MM, M, WORK, LWORK, INFO)
STREVC3
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 sgeevx(BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, WR, WI, VL, LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM, RCONDE, RCONDV, WORK, LWORK, IWORK, INFO)
SGEEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices ...
subroutine shseqr(JOB, COMPZ, N, ILO, IHI, H, LDH, WR, WI, Z, LDZ, WORK, LWORK, INFO)
SHSEQR
subroutine strsna(JOB, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, S, SEP, MM, M, WORK, LDWORK, IWORK, INFO)
STRSNA
subroutine sscal(N, SA, SX, INCX)
SSCAL
subroutine srot(N, SX, INCX, SY, INCY, C, S)
SROT
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.