301 SUBROUTINE dgeevx( 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
314 DOUBLE PRECISION ABNRM
318 DOUBLE PRECISION A( LDA, * ), RCONDE( * ), RCONDV( * ),
319 $ SCALE( * ), VL( LDVL, * ), VR( LDVR, * ),
320 $ wi( * ), work( * ), wr( * )
326 DOUBLE PRECISION ZERO, ONE
327 PARAMETER ( ZERO = 0.0d0, one = 1.0d0 )
330 LOGICAL LQUERY, SCALEA, WANTVL, WANTVR, WNTSNB, WNTSNE,
333 INTEGER HSWORK, I, ICOND, IERR, ITAU, IWRK, K,
334 $ LWORK_TREVC, MAXWRK, MINWRK, NOUT
335 DOUBLE PRECISION ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
340 DOUBLE PRECISION DUM( 1 )
350 INTEGER IDAMAX, ILAENV
351 DOUBLE PRECISION DLAMCH, DLANGE, DLAPY2, DNRM2
352 EXTERNAL lsame, idamax, ilaenv, dlamch, dlange,
364 lquery = ( lwork.EQ.-1 )
365 wantvl = lsame( jobvl,
'V' )
366 wantvr = lsame( jobvr,
'V' )
367 wntsnn = lsame( sense,
'N' )
368 wntsne = lsame( sense,
'E' )
369 wntsnv = lsame( sense,
'V' )
370 wntsnb = lsame( sense,
'B' )
371 IF( .NOT.( lsame( balanc,
'N' ) .OR. lsame( balanc,
'S' )
373 $ lsame( balanc,
'P' ) .OR.
374 $ lsame( balanc,
'B' ) ) )
377 ELSE IF( ( .NOT.wantvl ) .AND.
378 $ ( .NOT.lsame( jobvl,
'N' ) ) )
THEN
380 ELSE IF( ( .NOT.wantvr ) .AND.
381 $ ( .NOT.lsame( jobvr,
'N' ) ) )
THEN
383 ELSE IF( .NOT.( wntsnn .OR. wntsne .OR. wntsnb .OR. wntsnv ) .OR.
384 $ ( ( wntsne .OR. wntsnb ) .AND. .NOT.( wantvl .AND.
387 ELSE IF( n.LT.0 )
THEN
389 ELSE IF( lda.LT.max( 1, n ) )
THEN
391 ELSE IF( ldvl.LT.1 .OR. ( wantvl .AND. ldvl.LT.n ) )
THEN
393 ELSE IF( ldvr.LT.1 .OR. ( wantvr .AND. ldvr.LT.n ) )
THEN
412 maxwrk = n + n*ilaenv( 1,
'DGEHRD',
' ', n, 1, n, 0 )
415 CALL dtrevc3(
'L',
'B',
SELECT, n, a, lda,
416 $ vl, ldvl, vr, ldvr,
417 $ n, nout, work, -1, ierr )
418 lwork_trevc = int( work(1) )
419 maxwrk = max( maxwrk, n + lwork_trevc )
420 CALL dhseqr(
'S',
'V', n, 1, n, a, lda, wr, wi, vl,
423 ELSE IF( wantvr )
THEN
424 CALL dtrevc3(
'R',
'B',
SELECT, n, a, lda,
425 $ vl, ldvl, vr, ldvr,
426 $ n, nout, work, -1, ierr )
427 lwork_trevc = int( work(1) )
428 maxwrk = max( maxwrk, n + lwork_trevc )
429 CALL dhseqr(
'S',
'V', n, 1, n, a, lda, wr, wi, vr,
434 CALL dhseqr(
'E',
'N', n, 1, n, a, lda, wr, wi, vr,
435 $ ldvr, work, -1, info )
437 CALL dhseqr(
'S',
'N', n, 1, n, a, lda, wr, wi, vr,
438 $ ldvr, work, -1, info )
441 hswork = int( work(1) )
443 IF( ( .NOT.wantvl ) .AND. ( .NOT.wantvr ) )
THEN
446 $ minwrk = max( minwrk, n*n+6*n )
447 maxwrk = max( maxwrk, hswork )
449 $ maxwrk = max( maxwrk, n*n + 6*n )
452 IF( ( .NOT.wntsnn ) .AND. ( .NOT.wntsne ) )
453 $ minwrk = max( minwrk, n*n + 6*n )
454 maxwrk = max( maxwrk, hswork )
455 maxwrk = max( maxwrk, n + ( n - 1 )*ilaenv( 1,
457 $
' ', n, 1, n, -1 ) )
458 IF( ( .NOT.wntsnn ) .AND. ( .NOT.wntsne ) )
459 $ maxwrk = max( maxwrk, n*n + 6*n )
460 maxwrk = max( maxwrk, 3*n )
462 maxwrk = max( maxwrk, minwrk )
466 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
472 CALL xerbla(
'DGEEVX', -info )
474 ELSE IF( lquery )
THEN
486 smlnum = dlamch(
'S' )
487 bignum = one / smlnum
488 smlnum = sqrt( smlnum ) / eps
489 bignum = one / smlnum
494 anrm = dlange(
'M', n, n, a, lda, dum )
496 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
499 ELSE IF( anrm.GT.bignum )
THEN
504 $
CALL dlascl(
'G', 0, 0, anrm, cscale, n, n, a, lda, ierr )
508 CALL dgebal( balanc, n, a, lda, ilo, ihi, scale, ierr )
509 abnrm = dlange(
'1', n, n, a, lda, dum )
512 CALL dlascl(
'G', 0, 0, cscale, anrm, 1, 1, dum, 1, ierr )
521 CALL dgehrd( n, ilo, ihi, a, lda, work( itau ), work( iwrk ),
522 $ lwork-iwrk+1, ierr )
530 CALL dlacpy(
'L', n, n, a, lda, vl, ldvl )
535 CALL dorghr( n, ilo, ihi, vl, ldvl, work( itau ),
537 $ lwork-iwrk+1, ierr )
543 CALL dhseqr(
'S',
'V', n, ilo, ihi, a, lda, wr, wi, vl,
545 $ work( iwrk ), lwork-iwrk+1, info )
553 CALL dlacpy(
'F', n, n, vl, ldvl, vr, ldvr )
556 ELSE IF( wantvr )
THEN
562 CALL dlacpy(
'L', n, n, a, lda, vr, ldvr )
567 CALL dorghr( n, ilo, ihi, vr, ldvr, work( itau ),
569 $ lwork-iwrk+1, ierr )
575 CALL dhseqr(
'S',
'V', n, ilo, ihi, a, lda, wr, wi, vr,
577 $ work( iwrk ), lwork-iwrk+1, info )
593 CALL dhseqr( job,
'N', n, ilo, ihi, a, lda, wr, wi, vr,
595 $ work( iwrk ), lwork-iwrk+1, info )
603 IF( wantvl .OR. wantvr )
THEN
608 CALL dtrevc3( side,
'B',
SELECT, n, a, lda, vl, ldvl, vr,
610 $ n, nout, work( iwrk ), lwork-iwrk+1, ierr )
616 IF( .NOT.wntsnn )
THEN
617 CALL dtrsna( sense,
'A',
SELECT, n, a, lda, vl, ldvl, vr,
619 $ rconde, rcondv, n, nout, work( iwrk ), n, iwork,
627 CALL dgebak( balanc,
'L', n, ilo, ihi, scale, n, vl, ldvl,
633 IF( wi( i ).EQ.zero )
THEN
634 scl = one / dnrm2( n, vl( 1, i ), 1 )
635 CALL dscal( n, scl, vl( 1, i ), 1 )
636 ELSE IF( wi( i ).GT.zero )
THEN
637 scl = one / dlapy2( dnrm2( n, vl( 1, i ), 1 ),
638 $ dnrm2( n, vl( 1, i+1 ), 1 ) )
639 CALL dscal( n, scl, vl( 1, i ), 1 )
640 CALL dscal( n, scl, vl( 1, i+1 ), 1 )
642 work( k ) = vl( k, i )**2 + vl( k, i+1 )**2
644 k = idamax( n, work, 1 )
645 CALL dlartg( vl( k, i ), vl( k, i+1 ), cs, sn, r )
646 CALL drot( n, vl( 1, i ), 1, vl( 1, i+1 ), 1, cs, sn )
656 CALL dgebak( balanc,
'R', n, ilo, ihi, scale, n, vr, ldvr,
662 IF( wi( i ).EQ.zero )
THEN
663 scl = one / dnrm2( n, vr( 1, i ), 1 )
664 CALL dscal( n, scl, vr( 1, i ), 1 )
665 ELSE IF( wi( i ).GT.zero )
THEN
666 scl = one / dlapy2( dnrm2( n, vr( 1, i ), 1 ),
667 $ dnrm2( n, vr( 1, i+1 ), 1 ) )
668 CALL dscal( n, scl, vr( 1, i ), 1 )
669 CALL dscal( n, scl, vr( 1, i+1 ), 1 )
671 work( k ) = vr( k, i )**2 + vr( k, i+1 )**2
673 k = idamax( n, work, 1 )
674 CALL dlartg( vr( k, i ), vr( k, i+1 ), cs, sn, r )
675 CALL drot( n, vr( 1, i ), 1, vr( 1, i+1 ), 1, cs, sn )
685 CALL dlascl(
'G', 0, 0, cscale, anrm, n-info, 1,
687 $ max( n-info, 1 ), ierr )
688 CALL dlascl(
'G', 0, 0, cscale, anrm, n-info, 1,
690 $ max( n-info, 1 ), ierr )
692 IF( ( wntsnv .OR. wntsnb ) .AND. icond.EQ.0 )
693 $
CALL dlascl(
'G', 0, 0, cscale, anrm, n, 1, rcondv, n,
696 CALL dlascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, wr, n,
698 CALL dlascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, wi, n,