285 SUBROUTINE zgeevx( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, W, VL,
286 $ LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM, RCONDE,
287 $ RCONDV, WORK, LWORK, RWORK, INFO )
295 CHARACTER BALANC, JOBVL, JOBVR, SENSE
296 INTEGER IHI, ILO, INFO, LDA, LDVL, LDVR, LWORK, N
297 DOUBLE PRECISION ABNRM
300 DOUBLE PRECISION RCONDE( * ), RCONDV( * ), RWORK( * ),
302 COMPLEX*16 A( lda, * ), VL( ldvl, * ), VR( ldvr, * ),
309 DOUBLE PRECISION ZERO, ONE
310 parameter( zero = 0.0d0, one = 1.0d0 )
313 LOGICAL LQUERY, SCALEA, WANTVL, WANTVR, WNTSNB, WNTSNE,
316 INTEGER HSWORK, I, ICOND, IERR, ITAU, IWRK, K,
317 $ lwork_trevc, maxwrk, minwrk, nout
318 DOUBLE PRECISION ANRM, BIGNUM, CSCALE, EPS, SCL, SMLNUM
323 DOUBLE PRECISION DUM( 1 )
332 INTEGER IDAMAX, ILAENV
333 DOUBLE PRECISION DLAMCH, DZNRM2, ZLANGE
334 EXTERNAL lsame, idamax, ilaenv, dlamch, dznrm2, zlange
337 INTRINSIC dble, dcmplx, conjg, aimag, max, sqrt
344 lquery = ( lwork.EQ.-1 )
345 wantvl = lsame( jobvl,
'V' )
346 wantvr = lsame( jobvr,
'V' )
347 wntsnn = lsame( sense,
'N' )
348 wntsne = lsame( sense,
'E' )
349 wntsnv = lsame( sense,
'V' )
350 wntsnb = lsame( sense,
'B' )
351 IF( .NOT.( lsame( balanc,
'N' ) .OR. lsame( balanc,
'S' ) .OR.
352 $ lsame( balanc,
'P' ) .OR. lsame( balanc,
'B' ) ) )
THEN 354 ELSE IF( ( .NOT.wantvl ) .AND. ( .NOT.lsame( jobvl,
'N' ) ) )
THEN 356 ELSE IF( ( .NOT.wantvr ) .AND. ( .NOT.lsame( jobvr,
'N' ) ) )
THEN 358 ELSE IF( .NOT.( wntsnn .OR. wntsne .OR. wntsnb .OR. wntsnv ) .OR.
359 $ ( ( wntsne .OR. wntsnb ) .AND. .NOT.( wantvl .AND.
362 ELSE IF( n.LT.0 )
THEN 364 ELSE IF( lda.LT.max( 1, n ) )
THEN 366 ELSE IF( ldvl.LT.1 .OR. ( wantvl .AND. ldvl.LT.n ) )
THEN 368 ELSE IF( ldvr.LT.1 .OR. ( wantvr .AND. ldvr.LT.n ) )
THEN 388 maxwrk = n + n*ilaenv( 1,
'ZGEHRD',
' ', n, 1, n, 0 )
391 CALL ztrevc3(
'L',
'B',
SELECT, n, a, lda,
392 $ vl, ldvl, vr, ldvr,
393 $ n, nout, work, -1, rwork, -1, ierr )
394 lwork_trevc = int( work(1) )
395 maxwrk = max( maxwrk, lwork_trevc )
396 CALL zhseqr(
'S',
'V', n, 1, n, a, lda, w, vl, ldvl,
398 ELSE IF( wantvr )
THEN 399 CALL ztrevc3(
'R',
'B',
SELECT, n, a, lda,
400 $ vl, ldvl, vr, ldvr,
401 $ n, nout, work, -1, rwork, -1, ierr )
402 lwork_trevc = int( work(1) )
403 maxwrk = max( maxwrk, lwork_trevc )
404 CALL zhseqr(
'S',
'V', n, 1, n, a, lda, w, vr, ldvr,
408 CALL zhseqr(
'E',
'N', n, 1, n, a, lda, w, vr, ldvr,
411 CALL zhseqr(
'S',
'N', n, 1, n, a, lda, w, vr, ldvr,
415 hswork = int( work(1) )
417 IF( ( .NOT.wantvl ) .AND. ( .NOT.wantvr ) )
THEN 419 IF( .NOT.( wntsnn .OR. wntsne ) )
420 $ minwrk = max( minwrk, n*n + 2*n )
421 maxwrk = max( maxwrk, hswork )
422 IF( .NOT.( wntsnn .OR. wntsne ) )
423 $ maxwrk = max( maxwrk, n*n + 2*n )
426 IF( .NOT.( wntsnn .OR. wntsne ) )
427 $ minwrk = max( minwrk, n*n + 2*n )
428 maxwrk = max( maxwrk, hswork )
429 maxwrk = max( maxwrk, n + ( n - 1 )*ilaenv( 1,
'ZUNGHR',
430 $
' ', n, 1, n, -1 ) )
431 IF( .NOT.( wntsnn .OR. wntsne ) )
432 $ maxwrk = max( maxwrk, n*n + 2*n )
433 maxwrk = max( maxwrk, 2*n )
435 maxwrk = max( maxwrk, minwrk )
439 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN 445 CALL xerbla(
'ZGEEVX', -info )
447 ELSE IF( lquery )
THEN 459 smlnum = dlamch(
'S' )
460 bignum = one / smlnum
461 CALL dlabad( smlnum, bignum )
462 smlnum = sqrt( smlnum ) / eps
463 bignum = one / smlnum
468 anrm = zlange(
'M', n, n, a, lda, dum )
470 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN 473 ELSE IF( anrm.GT.bignum )
THEN 478 $
CALL zlascl(
'G', 0, 0, anrm, cscale, n, n, a, lda, ierr )
482 CALL zgebal( balanc, n, a, lda, ilo, ihi, scale, ierr )
483 abnrm = zlange(
'1', n, n, a, lda, dum )
486 CALL dlascl(
'G', 0, 0, cscale, anrm, 1, 1, dum, 1, ierr )
496 CALL zgehrd( n, ilo, ihi, a, lda, work( itau ), work( iwrk ),
497 $ lwork-iwrk+1, ierr )
505 CALL zlacpy(
'L', n, n, a, lda, vl, ldvl )
511 CALL zunghr( n, ilo, ihi, vl, ldvl, work( itau ), work( iwrk ),
512 $ lwork-iwrk+1, ierr )
519 CALL zhseqr(
'S',
'V', n, ilo, ihi, a, lda, w, vl, ldvl,
520 $ work( iwrk ), lwork-iwrk+1, info )
528 CALL zlacpy(
'F', n, n, vl, ldvl, vr, ldvr )
531 ELSE IF( wantvr )
THEN 537 CALL zlacpy(
'L', n, n, a, lda, vr, ldvr )
543 CALL zunghr( n, ilo, ihi, vr, ldvr, work( itau ), work( iwrk ),
544 $ lwork-iwrk+1, ierr )
551 CALL zhseqr(
'S',
'V', n, ilo, ihi, a, lda, w, vr, ldvr,
552 $ work( iwrk ), lwork-iwrk+1, info )
569 CALL zhseqr( job,
'N', n, ilo, ihi, a, lda, w, vr, ldvr,
570 $ work( iwrk ), lwork-iwrk+1, info )
578 IF( wantvl .OR. wantvr )
THEN 584 CALL ztrevc3( side,
'B',
SELECT, n, a, lda, vl, ldvl, vr, ldvr,
585 $ n, nout, work( iwrk ), lwork-iwrk+1,
593 IF( .NOT.wntsnn )
THEN 594 CALL ztrsna( sense,
'A',
SELECT, n, a, lda, vl, ldvl, vr, ldvr,
595 $ rconde, rcondv, n, nout, work( iwrk ), n, rwork,
603 CALL zgebak( balanc,
'L', n, ilo, ihi, scale, n, vl, ldvl,
609 scl = one / dznrm2( n, vl( 1, i ), 1 )
610 CALL zdscal( n, scl, vl( 1, i ), 1 )
612 rwork( k ) = dble( vl( k, i ) )**2 +
613 $ aimag( vl( k, i ) )**2
615 k = idamax( n, rwork, 1 )
616 tmp = conjg( vl( k, i ) ) / sqrt( rwork( k ) )
617 CALL zscal( n, tmp, vl( 1, i ), 1 )
618 vl( k, i ) = dcmplx( dble( vl( k, i ) ), zero )
626 CALL zgebak( balanc,
'R', n, ilo, ihi, scale, n, vr, ldvr,
632 scl = one / dznrm2( n, vr( 1, i ), 1 )
633 CALL zdscal( n, scl, vr( 1, i ), 1 )
635 rwork( k ) = dble( vr( k, i ) )**2 +
636 $ aimag( vr( k, i ) )**2
638 k = idamax( n, rwork, 1 )
639 tmp = conjg( vr( k, i ) ) / sqrt( rwork( k ) )
640 CALL zscal( n, tmp, vr( 1, i ), 1 )
641 vr( k, i ) = dcmplx( dble( vr( k, i ) ), zero )
649 CALL zlascl(
'G', 0, 0, cscale, anrm, n-info, 1, w( info+1 ),
650 $ max( n-info, 1 ), ierr )
652 IF( ( wntsnv .OR. wntsnb ) .AND. icond.EQ.0 )
653 $
CALL dlascl(
'G', 0, 0, cscale, anrm, n, 1, rcondv, n,
656 CALL zlascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, w, n, ierr )
subroutine ztrevc3(SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, MM, M, WORK, LWORK, RWORK, LRWORK, INFO)
ZTREVC3
subroutine zdscal(N, DA, ZX, INCX)
ZDSCAL
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine zunghr(N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO)
ZUNGHR
subroutine zgehrd(N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO)
ZGEHRD
subroutine zgeevx(BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, W, VL, LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM, RCONDE, RCONDV, WORK, LWORK, RWORK, INFO)
ZGEEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices ...
subroutine zlascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
ZLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine zlacpy(UPLO, M, N, A, LDA, B, LDB)
ZLACPY copies all or part of one two-dimensional array to another.
subroutine zhseqr(JOB, COMPZ, N, ILO, IHI, H, LDH, W, Z, LDZ, WORK, LWORK, INFO)
ZHSEQR
subroutine zgebal(JOB, N, A, LDA, ILO, IHI, SCALE, INFO)
ZGEBAL
subroutine ztrsna(JOB, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, S, SEP, MM, M, WORK, LDWORK, RWORK, INFO)
ZTRSNA
subroutine dlascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine zgebak(JOB, SIDE, N, ILO, IHI, SCALE, M, V, LDV, INFO)
ZGEBAK
subroutine dlabad(SMALL, LARGE)
DLABAD
subroutine zscal(N, ZA, ZX, INCX)
ZSCAL