283 SUBROUTINE cgeevx( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, W,
285 $ LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM, RCONDE,
286 $ RCONDV, WORK, LWORK, RWORK, INFO )
294 CHARACTER BALANC, JOBVL, JOBVR, SENSE
295 INTEGER IHI, ILO, INFO, LDA, LDVL, LDVR, LWORK, N
299 REAL RCONDE( * ), RCONDV( * ), RWORK( * ),
301 COMPLEX A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
309 PARAMETER ( ZERO = 0.0e0, one = 1.0e0 )
312 LOGICAL LQUERY, SCALEA, WANTVL, WANTVR, WNTSNB, WNTSNE,
315 INTEGER HSWORK, I, ICOND, IERR, ITAU, IWRK, K,
316 $ LWORK_TREVC, MAXWRK, MINWRK, NOUT
317 REAL ANRM, BIGNUM, CSCALE, EPS, SCL, SMLNUM
333 INTEGER ISAMAX, ILAENV
334 REAL SLAMCH, SCNRM2, CLANGE,
336 EXTERNAL lsame, isamax, ilaenv,
337 $ slamch, scnrm2, clange,
341 INTRINSIC real, cmplx, conjg, aimag, max, sqrt
348 lquery = ( lwork.EQ.-1 )
349 wantvl = lsame( jobvl,
'V' )
350 wantvr = lsame( jobvr,
'V' )
351 wntsnn = lsame( sense,
'N' )
352 wntsne = lsame( sense,
'E' )
353 wntsnv = lsame( sense,
'V' )
354 wntsnb = lsame( sense,
'B' )
355 IF( .NOT.( lsame( balanc,
'N' ) .OR.
356 $ lsame( balanc,
'S' ) .OR.
357 $ lsame( balanc,
'P' ) .OR. lsame( balanc,
'B' ) ) )
THEN
359 ELSE IF( ( .NOT.wantvl ) .AND.
360 $ ( .NOT.lsame( jobvl,
'N' ) ) )
THEN
362 ELSE IF( ( .NOT.wantvr ) .AND.
363 $ ( .NOT.lsame( jobvr,
'N' ) ) )
THEN
365 ELSE IF( .NOT.( wntsnn .OR. wntsne .OR. wntsnb .OR. wntsnv ) .OR.
366 $ ( ( wntsne .OR. wntsnb ) .AND. .NOT.( wantvl .AND.
369 ELSE IF( n.LT.0 )
THEN
371 ELSE IF( lda.LT.max( 1, n ) )
THEN
373 ELSE IF( ldvl.LT.1 .OR. ( wantvl .AND. ldvl.LT.n ) )
THEN
375 ELSE IF( ldvr.LT.1 .OR. ( wantvr .AND. ldvr.LT.n ) )
THEN
395 maxwrk = n + n*ilaenv( 1,
'CGEHRD',
' ', n, 1, n, 0 )
398 CALL ctrevc3(
'L',
'B',
SELECT, n, a, lda,
399 $ vl, ldvl, vr, ldvr,
400 $ n, nout, work, -1, rwork, -1, ierr )
401 lwork_trevc = int( work(1) )
402 maxwrk = max( maxwrk, lwork_trevc )
403 CALL chseqr(
'S',
'V', n, 1, n, a, lda, w, vl, ldvl,
405 ELSE IF( wantvr )
THEN
406 CALL ctrevc3(
'R',
'B',
SELECT, n, a, lda,
407 $ vl, ldvl, vr, ldvr,
408 $ n, nout, work, -1, rwork, -1, ierr )
409 lwork_trevc = int( work(1) )
410 maxwrk = max( maxwrk, lwork_trevc )
411 CALL chseqr(
'S',
'V', n, 1, n, a, lda, w, vr, ldvr,
415 CALL chseqr(
'E',
'N', n, 1, n, a, lda, w, vr,
419 CALL chseqr(
'S',
'N', n, 1, n, a, lda, w, vr,
424 hswork = int( work(1) )
426 IF( ( .NOT.wantvl ) .AND. ( .NOT.wantvr ) )
THEN
428 IF( .NOT.( wntsnn .OR. wntsne ) )
429 $ minwrk = max( minwrk, n*n + 2*n )
430 maxwrk = max( maxwrk, hswork )
431 IF( .NOT.( wntsnn .OR. wntsne ) )
432 $ maxwrk = max( maxwrk, n*n + 2*n )
435 IF( .NOT.( wntsnn .OR. wntsne ) )
436 $ minwrk = max( minwrk, n*n + 2*n )
437 maxwrk = max( maxwrk, hswork )
438 maxwrk = max( maxwrk, n + ( n - 1 )*ilaenv( 1,
440 $
' ', n, 1, n, -1 ) )
441 IF( .NOT.( wntsnn .OR. wntsne ) )
442 $ maxwrk = max( maxwrk, n*n + 2*n )
443 maxwrk = max( maxwrk, 2*n )
445 maxwrk = max( maxwrk, minwrk )
449 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
455 CALL xerbla(
'CGEEVX', -info )
457 ELSE IF( lquery )
THEN
469 smlnum = slamch(
'S' )
470 bignum = one / smlnum
471 smlnum = sqrt( smlnum ) / eps
472 bignum = one / smlnum
477 anrm = clange(
'M', n, n, a, lda, dum )
479 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
482 ELSE IF( anrm.GT.bignum )
THEN
487 $
CALL clascl(
'G', 0, 0, anrm, cscale, n, n, a, lda, ierr )
491 CALL cgebal( balanc, n, a, lda, ilo, ihi, scale, ierr )
492 abnrm = clange(
'1', n, n, a, lda, dum )
495 CALL slascl(
'G', 0, 0, cscale, anrm, 1, 1, dum, 1, ierr )
505 CALL cgehrd( n, ilo, ihi, a, lda, work( itau ), work( iwrk ),
506 $ lwork-iwrk+1, ierr )
514 CALL clacpy(
'L', n, n, a, lda, vl, ldvl )
520 CALL cunghr( n, ilo, ihi, vl, ldvl, work( itau ),
522 $ lwork-iwrk+1, ierr )
529 CALL chseqr(
'S',
'V', n, ilo, ihi, a, lda, w, vl, ldvl,
530 $ work( iwrk ), lwork-iwrk+1, info )
538 CALL clacpy(
'F', n, n, vl, ldvl, vr, ldvr )
541 ELSE IF( wantvr )
THEN
547 CALL clacpy(
'L', n, n, a, lda, vr, ldvr )
553 CALL cunghr( n, ilo, ihi, vr, ldvr, work( itau ),
555 $ lwork-iwrk+1, ierr )
562 CALL chseqr(
'S',
'V', n, ilo, ihi, a, lda, w, vr, ldvr,
563 $ work( iwrk ), lwork-iwrk+1, info )
580 CALL chseqr( job,
'N', n, ilo, ihi, a, lda, w, vr, ldvr,
581 $ work( iwrk ), lwork-iwrk+1, info )
589 IF( wantvl .OR. wantvr )
THEN
595 CALL ctrevc3( side,
'B',
SELECT, n, a, lda, vl, ldvl, vr,
597 $ n, nout, work( iwrk ), lwork-iwrk+1,
605 IF( .NOT.wntsnn )
THEN
606 CALL ctrsna( sense,
'A',
SELECT, n, a, lda, vl, ldvl, vr,
608 $ rconde, rcondv, n, nout, work( iwrk ), n, rwork,
616 CALL cgebak( balanc,
'L', n, ilo, ihi, scale, n, vl, ldvl,
622 scl = one / scnrm2( n, vl( 1, i ), 1 )
623 CALL csscal( n, scl, vl( 1, i ), 1 )
625 rwork( k ) = real( vl( k, i ) )**2 +
626 $ aimag( vl( k, i ) )**2
628 k = isamax( n, rwork, 1 )
629 tmp = conjg( vl( k, i ) ) / sqrt( rwork( k ) )
630 CALL cscal( n, tmp, vl( 1, i ), 1 )
631 vl( k, i ) = cmplx( real( vl( k, i ) ), zero )
639 CALL cgebak( balanc,
'R', n, ilo, ihi, scale, n, vr, ldvr,
645 scl = one / scnrm2( n, vr( 1, i ), 1 )
646 CALL csscal( n, scl, vr( 1, i ), 1 )
648 rwork( k ) = real( vr( k, i ) )**2 +
649 $ aimag( vr( k, i ) )**2
651 k = isamax( n, rwork, 1 )
652 tmp = conjg( vr( k, i ) ) / sqrt( rwork( k ) )
653 CALL cscal( n, tmp, vr( 1, i ), 1 )
654 vr( k, i ) = cmplx( real( vr( k, i ) ), zero )
662 CALL clascl(
'G', 0, 0, cscale, anrm, n-info, 1,
664 $ max( n-info, 1 ), ierr )
666 IF( ( wntsnv .OR. wntsnb ) .AND. icond.EQ.0 )
667 $
CALL slascl(
'G', 0, 0, cscale, anrm, n, 1, rcondv, n,
670 CALL clascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, w, n,