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 , JOBVL, JOBVR, SENSE
296 INTEGER IHI, ILO, INFO, LDA, LDVL, LDVR, LWORK, N
300 REAL ( * ), 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
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
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,
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,
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 )