285 SUBROUTINE cgeevx( 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
300 REAL RCONDE( * ), RCONDV( * ), RWORK( * ),
302 COMPLEX A( lda, * ), VL( ldvl, * ), VR( ldvr, * ),
310 parameter( zero = 0.0e0, one = 1.0e0 )
313 LOGICAL LQUERY, SCALEA, WANTVL, WANTVR, WNTSNB, WNTSNE,
316 INTEGER HSWORK, I, ICOND, IERR, ITAU, IWRK, K,
317 $ lwork_trevc, maxwrk, minwrk, nout
318 REAL ANRM, BIGNUM, CSCALE, EPS, SCL, SMLNUM
332 INTEGER ISAMAX, ILAENV
333 REAL SLAMCH, SCNRM2, CLANGE
334 EXTERNAL lsame, isamax, ilaenv, slamch, scnrm2, clange
337 INTRINSIC REAL, CMPLX, 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,
'CGEHRD',
' ', n, 1, n, 0 )
391 CALL ctrevc3(
'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 chseqr(
'S',
'V', n, 1, n, a, lda, w, vl, ldvl,
398 ELSE IF( wantvr )
THEN 399 CALL ctrevc3(
'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 chseqr(
'S',
'V', n, 1, n, a, lda, w, vr, ldvr,
408 CALL chseqr(
'E',
'N', n, 1, n, a, lda, w, vr, ldvr,
411 CALL chseqr(
'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,
'CUNGHR',
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(
'CGEEVX', -info )
447 ELSE IF( lquery )
THEN 459 smlnum = slamch(
'S' )
460 bignum = one / smlnum
461 CALL slabad( smlnum, bignum )
462 smlnum = sqrt( smlnum ) / eps
463 bignum = one / smlnum
468 anrm = clange(
'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 clascl(
'G', 0, 0, anrm, cscale, n, n, a, lda, ierr )
482 CALL cgebal( balanc, n, a, lda, ilo, ihi, scale, ierr )
483 abnrm = clange(
'1', n, n, a, lda, dum )
486 CALL slascl(
'G', 0, 0, cscale, anrm, 1, 1, dum, 1, ierr )
496 CALL cgehrd( n, ilo, ihi, a, lda, work( itau ), work( iwrk ),
497 $ lwork-iwrk+1, ierr )
505 CALL clacpy(
'L', n, n, a, lda, vl, ldvl )
511 CALL cunghr( n, ilo, ihi, vl, ldvl, work( itau ), work( iwrk ),
512 $ lwork-iwrk+1, ierr )
519 CALL chseqr(
'S',
'V', n, ilo, ihi, a, lda, w, vl, ldvl,
520 $ work( iwrk ), lwork-iwrk+1, info )
528 CALL clacpy(
'F', n, n, vl, ldvl, vr, ldvr )
531 ELSE IF( wantvr )
THEN 537 CALL clacpy(
'L', n, n, a, lda, vr, ldvr )
543 CALL cunghr( n, ilo, ihi, vr, ldvr, work( itau ), work( iwrk ),
544 $ lwork-iwrk+1, ierr )
551 CALL chseqr(
'S',
'V', n, ilo, ihi, a, lda, w, vr, ldvr,
552 $ work( iwrk ), lwork-iwrk+1, info )
569 CALL chseqr( 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 ctrevc3( 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 ctrsna( sense,
'A',
SELECT, n, a, lda, vl, ldvl, vr, ldvr,
595 $ rconde, rcondv, n, nout, work( iwrk ), n, rwork,
603 CALL cgebak( balanc,
'L', n, ilo, ihi, scale, n, vl, ldvl,
609 scl = one / scnrm2( n, vl( 1, i ), 1 )
610 CALL csscal( n, scl, vl( 1, i ), 1 )
612 rwork( k ) =
REAL( VL( K, I ) )**2 +
613 $ aimag( vl( k, i ) )**2
615 k = isamax( n, rwork, 1 )
616 tmp = conjg( vl( k, i ) ) / sqrt( rwork( k ) )
617 CALL cscal( n, tmp, vl( 1, i ), 1 )
618 vl( k, i ) = cmplx(
REAL( VL( K, I ) ), ZERO )
626 CALL cgebak( balanc,
'R', n, ilo, ihi, scale, n, vr, ldvr,
632 scl = one / scnrm2( n, vr( 1, i ), 1 )
633 CALL csscal( n, scl, vr( 1, i ), 1 )
635 rwork( k ) =
REAL( VR( K, I ) )**2 +
636 $ aimag( vr( k, i ) )**2
638 k = isamax( n, rwork, 1 )
639 tmp = conjg( vr( k, i ) ) / sqrt( rwork( k ) )
640 CALL cscal( n, tmp, vr( 1, i ), 1 )
641 vr( k, i ) = cmplx(
REAL( VR( K, I ) ), ZERO )
649 CALL clascl(
'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 slascl(
'G', 0, 0, cscale, anrm, n, 1, rcondv, n,
656 CALL clascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, w, n, ierr )
subroutine clacpy(UPLO, M, N, A, LDA, B, LDB)
CLACPY copies all or part of one two-dimensional array to another.
subroutine cgeevx(BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, W, VL, LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM, RCONDE, RCONDV, WORK, LWORK, RWORK, INFO)
CGEEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices ...
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine csscal(N, SA, CX, INCX)
CSSCAL
subroutine cscal(N, CA, CX, INCX)
CSCAL
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 ctrevc3(SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, MM, M, WORK, LWORK, RWORK, LRWORK, INFO)
CTREVC3
subroutine clascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
CLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine ctrsna(JOB, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, S, SEP, MM, M, WORK, LDWORK, RWORK, INFO)
CTRSNA
subroutine cgehrd(N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO)
CGEHRD
subroutine cunghr(N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO)
CUNGHR
subroutine chseqr(JOB, COMPZ, N, ILO, IHI, H, LDH, W, Z, LDZ, WORK, LWORK, INFO)
CHSEQR
subroutine cgebak(JOB, SIDE, N, ILO, IHI, SCALE, M, V, LDV, INFO)
CGEBAK
subroutine cgebal(JOB, N, A, LDA, ILO, IHI, SCALE, INFO)
CGEBAL