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 ),
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,