301 SUBROUTINE sgeevx( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, WR,
303 $ VL, LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM,
304 $ RCONDE, RCONDV, WORK, LWORK, IWORK, INFO )
312 CHARACTER BALANC, JOBVL, JOBVR, SENSE
313 INTEGER IHI, ILO, INFO, LDA, LDVL, LDVR, LWORK, N
318 REAL A( LDA, * ), RCONDE( * ), RCONDV( * ),
319 $ SCALE( * ), VL( LDVL, * ), VR( LDVR, * ),
320 $ wi( * ), work( * ), wr( * )
327 PARAMETER ( ZERO = 0.0e0, one = 1.0e0 )
330 LOGICAL LQUERY, SCALEA, WANTVL, WANTVR, WNTSNB, WNTSNE,
333 INTEGER HSWORK, I, ICOND, IERR, ITAU, IWRK, K,
334 $ LWORK_TREVC, MAXWRK, MINWRK, NOUT
335 REAL ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
350 INTEGER ISAMAX, ILAENV
351 REAL SLAMCH, SLANGE, SLAPY2,
353 EXTERNAL lsame, isamax, ilaenv,
354 $ slamch, slange, slapy2,
365 lquery = ( lwork.EQ.-1 )
366 wantvl = lsame( jobvl,
'V' )
367 wantvr = lsame( jobvr,
'V' )
368 wntsnn = lsame( sense,
'N' )
369 wntsne = lsame( sense,
'E' )
370 wntsnv = lsame( sense,
'V' )
371 wntsnb = lsame( sense,
'B' )
372 IF( .NOT.( lsame( balanc,
'N' ) .OR. lsame( balanc,
'S' )
374 $ lsame( balanc,
'P' ) .OR.
375 $ lsame( balanc,
'B' ) ) )
378 ELSE IF( ( .NOT.wantvl ) .AND.
379 $ ( .NOT.lsame( jobvl,
'N' ) ) )
THEN
381 ELSE IF( ( .NOT.wantvr ) .AND.
382 $ ( .NOT.lsame( jobvr,
'N' ) ) )
THEN
384 ELSE IF( .NOT.( wntsnn .OR. wntsne .OR. wntsnb .OR. wntsnv ) .OR.
385 $ ( ( wntsne .OR. wntsnb ) .AND. .NOT.( wantvl .AND.
388 ELSE IF( n.LT.0 )
THEN
390 ELSE IF( lda.LT.max( 1, n ) )
THEN
392 ELSE IF( ldvl.LT.1 .OR. ( wantvl .AND. ldvl.LT.n ) )
THEN
394 ELSE IF( ldvr.LT.1 .OR. ( wantvr .AND. ldvr.LT.n ) )
THEN
413 maxwrk = n + n*ilaenv( 1,
'SGEHRD',
' ', n, 1, n, 0 )
416 CALL strevc3(
'L',
'B',
SELECT, n, a, lda,
417 $ vl, ldvl, vr, ldvr,
418 $ n, nout, work, -1, ierr )
419 lwork_trevc = int( work(1) )
420 maxwrk = max( maxwrk, n + lwork_trevc )
421 CALL shseqr(
'S',
'V', n, 1, n, a, lda, wr, wi, vl,
424 ELSE IF( wantvr )
THEN
425 CALL strevc3(
'R',
'B',
SELECT, n, a, lda,
426 $ vl, ldvl, vr, ldvr,
427 $ n, nout, work, -1, ierr )
428 lwork_trevc = int( work(1) )
429 maxwrk = max( maxwrk, n + lwork_trevc )
430 CALL shseqr(
'S',
'V', n, 1, n, a, lda, wr, wi, vr,
435 CALL shseqr(
'E',
'N', n, 1, n, a, lda, wr, wi, vr,
436 $ ldvr, work, -1, info )
438 CALL shseqr(
'S',
'N', n, 1, n, a, lda, wr, wi, vr,
439 $ ldvr, work, -1, info )
442 hswork = int( work(1) )
444 IF( ( .NOT.wantvl ) .AND. ( .NOT.wantvr ) )
THEN
447 $ minwrk = max( minwrk, n*n+6*n )
448 maxwrk = max( maxwrk, hswork )
450 $ maxwrk = max( maxwrk, n*n + 6*n )
453 IF( ( .NOT.wntsnn ) .AND. ( .NOT.wntsne ) )
454 $ minwrk = max( minwrk, n*n + 6*n )
455 maxwrk = max( maxwrk, hswork )
456 maxwrk = max( maxwrk, n + ( n - 1 )*ilaenv( 1,
458 $
' ', n, 1, n, -1 ) )
459 IF( ( .NOT.wntsnn ) .AND. ( .NOT.wntsne ) )
460 $ maxwrk = max( maxwrk, n*n + 6*n )
461 maxwrk = max( maxwrk, 3*n )
463 maxwrk = max( maxwrk, minwrk )
467 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
473 CALL xerbla(
'SGEEVX', -info )
475 ELSE IF( lquery )
THEN
487 smlnum = slamch(
'S' )
488 bignum = one / smlnum
489 smlnum = sqrt( smlnum ) / eps
490 bignum = one / smlnum
495 anrm = slange(
'M', n, n, a, lda, dum )
497 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
500 ELSE IF( anrm.GT.bignum )
THEN
505 $
CALL slascl(
'G', 0, 0, anrm, cscale, n, n, a, lda, ierr )
509 CALL sgebal( balanc, n, a, lda, ilo, ihi, scale, ierr )
510 abnrm = slange(
'1', n, n, a, lda, dum )
513 CALL slascl(
'G', 0, 0, cscale, anrm, 1, 1, dum, 1, ierr )
522 CALL sgehrd( n, ilo, ihi, a, lda, work( itau ), work( iwrk ),
523 $ lwork-iwrk+1, ierr )
531 CALL slacpy(
'L', n, n, a, lda, vl, ldvl )
536 CALL sorghr( n, ilo, ihi, vl, ldvl, work( itau ),
538 $ lwork-iwrk+1, ierr )
544 CALL shseqr(
'S',
'V', n, ilo, ihi, a, lda, wr, wi, vl,
546 $ work( iwrk ), lwork-iwrk+1, info )
554 CALL slacpy(
'F', n, n, vl, ldvl, vr, ldvr )
557 ELSE IF( wantvr )
THEN
563 CALL slacpy(
'L', n, n, a, lda, vr, ldvr )
568 CALL sorghr( n, ilo, ihi, vr, ldvr, work( itau ),
570 $ lwork-iwrk+1, ierr )
576 CALL shseqr(
'S',
'V', n, ilo, ihi, a, lda, wr, wi, vr,
578 $ work( iwrk ), lwork-iwrk+1, info )
594 CALL shseqr( job,
'N', n, ilo, ihi, a, lda, wr, wi, vr,
596 $ work( iwrk ), lwork-iwrk+1, info )
604 IF( wantvl .OR. wantvr )
THEN
609 CALL strevc3( side,
'B',
SELECT, n, a, lda, vl, ldvl, vr,
611 $ n, nout, work( iwrk ), lwork-iwrk+1, ierr )
617 IF( .NOT.wntsnn )
THEN
618 CALL strsna( sense,
'A',
SELECT, n, a, lda, vl, ldvl, vr,
620 $ rconde, rcondv, n, nout, work( iwrk ), n, iwork,
628 CALL sgebak( balanc,
'L', n, ilo, ihi, scale, n, vl, ldvl,
634 IF( wi( i ).EQ.zero )
THEN
635 scl = one /
snrm2( n, vl( 1, i ), 1 )
636 CALL sscal( n, scl, vl( 1, i ), 1 )
637 ELSE IF( wi( i ).GT.zero )
THEN
638 scl = one / slapy2(
snrm2( n, vl( 1, i ), 1 ),
639 $
snrm2( n, vl( 1, i+1 ), 1 ) )
640 CALL sscal( n, scl, vl( 1, i ), 1 )
641 CALL sscal( n, scl, vl( 1, i+1 ), 1 )
643 work( k ) = vl( k, i )**2 + vl( k, i+1 )**2
645 k = isamax( n, work, 1 )
646 CALL slartg( vl( k, i ), vl( k, i+1 ), cs, sn, r )
647 CALL srot( n, vl( 1, i ), 1, vl( 1, i+1 ), 1, cs, sn )
657 CALL sgebak( balanc,
'R', n, ilo, ihi, scale, n, vr, ldvr,
663 IF( wi( i ).EQ.zero )
THEN
664 scl = one /
snrm2( n, vr( 1, i ), 1 )
665 CALL sscal( n, scl, vr( 1, i ), 1 )
666 ELSE IF( wi( i ).GT.zero )
THEN
667 scl = one / slapy2(
snrm2( n, vr( 1, i ), 1 ),
668 $
snrm2( n, vr( 1, i+1 ), 1 ) )
669 CALL sscal( n, scl, vr( 1, i ), 1 )
670 CALL sscal( n, scl, vr( 1, i+1 ), 1 )
672 work( k ) = vr( k, i )**2 + vr( k, i+1 )**2
674 k = isamax( n, work, 1 )
675 CALL slartg( vr( k, i ), vr( k, i+1 ), cs, sn, r )
676 CALL srot( n, vr( 1, i ), 1, vr( 1, i+1 ), 1, cs, sn )
686 CALL slascl(
'G', 0, 0, cscale, anrm, n-info, 1,
688 $ max( n-info, 1 ), ierr )
689 CALL slascl(
'G', 0, 0, cscale, anrm, n-info, 1,
691 $ max( n-info, 1 ), ierr )
693 IF( ( wntsnv .OR. wntsnb ) .AND. icond.EQ.0 )
694 $
CALL slascl(
'G', 0, 0, cscale, anrm, n, 1, rcondv, n,
697 CALL slascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, wr, n,
699 CALL slascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, wi, n,