303 SUBROUTINE dgeevx( 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
315 DOUBLE PRECISION ABNRM
319 DOUBLE PRECISION A( LDA, * ), RCONDE( * ), RCONDV( * ),
320 $ scale( * ), vl( ldvl, * ), vr( ldvr, * ),
321 $ wi( * ), work( * ), wr( * )
327 DOUBLE PRECISION ZERO, ONE
328 PARAMETER ( ZERO = 0.0d0, one = 1.0d0 )
331 LOGICAL LQUERY, SCALEA, WANTVL, , WNTSNB, WNTSNE,
334 INTEGER HSWORK, I, ICOND, IERR, ITAU, IWRK, K,
335 $ lwork_trevc, maxwrk, minwrk, nout
336 DOUBLE PRECISION ANRM, BIGNUM, CS, CSCALE, EPS, , SCL, SMLNUM,
341 DOUBLE PRECISION DUM( 1 )
350 INTEGER IDAMAX, ILAENV
351 DOUBLE PRECISION DLAMCH, DLANGE, DLAPY2, DNRM2
352 EXTERNAL lsame, idamax, ilaenv, dlamch, dlange, dlapy2,
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' )
'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,
'DGEHRD',
' ', n, 1, n, 0 )
410 CALL dtrevc3(
'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 dhseqr(
'S',
'V', n, 1, n, a, lda, wr, wi, vl, ldvl,
417 ELSE IF( wantvr )
THEN
418 CALL dtrevc3(
'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 dhseqr( 's
', 'v
', N, 1, N, A, LDA, WR, WI, VR, LDVR,
427 CALL DHSEQR( 'e
', 'n
', N, 1, N, A, LDA, WR, WI, VR,
428 $ LDVR, WORK, -1, INFO )
430 CALL DHSEQR( 's
', 'n
', N, 1, N, A, LDA, WR, WI, VR,
431 $ LDVR, WORK, -1, INFO )
434 HSWORK = INT( WORK(1) )
436.NOT..AND..NOT.
IF( ( WANTVL ) ( WANTVR ) ) THEN
439 $ MINWRK = MAX( MINWRK, N*N+6*N )
440 MAXWRK = MAX( MAXWRK, HSWORK )
442 $ MAXWRK = MAX( MAXWRK, N*N + 6*N )
445.NOT..AND..NOT.
IF( ( WNTSNN ) ( WNTSNE ) )
446 $ MINWRK = MAX( MINWRK, N*N + 6*N )
447 MAXWRK = MAX( MAXWRK, HSWORK )
448 MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'dorghr',
449 $ ' ', N, 1, N, -1 ) )
450.NOT..AND..NOT.
IF( ( WNTSNN ) ( WNTSNE ) )
451 $ MAXWRK = MAX( MAXWRK, N*N + 6*N )
452 MAXWRK = MAX( MAXWRK, 3*N )
454 MAXWRK = MAX( MAXWRK, MINWRK )
458.LT..AND..NOT.
IF( LWORKMINWRK LQUERY ) THEN
464 CALL XERBLA( 'dgeevx', -INFO )
466 ELSE IF( LQUERY ) THEN
478 SMLNUM = DLAMCH( 's
' )
479 BIGNUM = ONE / SMLNUM
480 CALL DLABAD( SMLNUM, BIGNUM )
481 SMLNUM = SQRT( SMLNUM ) / EPS
482 BIGNUM = ONE / SMLNUM
487 ANRM = DLANGE( 'm
', N, N, A, LDA, DUM )
489.GT..AND..LT.
IF( ANRMZERO ANRMSMLNUM ) THEN
492.GT.
ELSE IF( ANRMBIGNUM ) THEN
497 $ CALL DLASCL( 'g
', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
501 CALL DGEBAL( BALANC, N, A, LDA, ILO, IHI, SCALE, IERR )
502 ABNRM = DLANGE( '1
', N, N, A, LDA, DUM )
505 CALL DLASCL( 'g
', 0, 0, CSCALE, ANRM, 1, 1, DUM, 1, IERR )
514 CALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
515 $ LWORK-IWRK+1, IERR )
523 CALL DLACPY( 'l
', N, N, A, LDA, VL, LDVL )
528 CALL DORGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),
529 $ LWORK-IWRK+1, IERR )
535 CALL DHSEQR( 's
', 'v
', N, ILO, IHI, A, LDA, WR, WI, VL, LDVL,
536 $ WORK( IWRK ), LWORK-IWRK+1, INFO )
544 CALL DLACPY( 'f', n, n, vl, ldvl, vr, ldvr )
547 ELSE IF( wantvr )
THEN
553 CALL dlacpy(
'L', n, n, a, lda, vr, ldvr )
558 CALL dorghr( n, ilo, ihi, vr, ldvr, work( itau ), work( iwrk ),
559 $ lwork-iwrk+1, ierr )
565 CALL dhseqr(
'S',
'V', n, ilo, ihi, a, lda, wr, wi, vr, ldvr,
566 $ work( iwrk ), lwork-iwrk+1, info )
582 CALL dhseqr( 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 dtrevc3( 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 dtrsna( sense,
'A',
SELECT, n, a, lda, vl, ldvl, vr, ldvr,
605 $ rconde, rcondv, n, nout, work( iwrk ), n, iwork,
613 CALL dgebak( balanc,
'L', n, ilo
619 IF( wi( i ).EQ.zero )
THEN
620 scl = one / dnrm2( n, vl( 1, i ), 1 )
621 CALL dscal( n, scl, vl( 1, i ), 1 )
622 ELSE IF( wi( i ).GT.zero )
THEN
625 CALL dscal( n, scl, vl( 1, i ), 1 )
626 CALL dscal( n, scl, vl( 1, i+1 ), 1 )
628 work( k ) = vl( k, i )**2 + vl( k, i+1 )**2
631 CALL dlartg( vl( k, i ), vl( k, i+1 ), cs, sn, r )
632 CALL drot( n, vl( 1, i ), 1, vl( 1, i+1 ), 1, cs, sn )
642 CALL dgebak( balanc,
'R', n, ilo, ihi, scale, n, vr, ldvr,
648 IF( wi( i ).EQ.zero )
THEN
649 scl = one / dnrm2( n, vr( 1, i ), 1 )
650 CALL dscal( n, scl, vr( 1, i ), 1 )
651 ELSE IF( wi( i ).GT.zero )
THEN
652 scl = one / dlapy2( dnrm2( n, vr( 1, i ), 1 ),
653 $ dnrm2( n, vr( 1, i+1 ), 1 ) )
654 CALL dscal( n, scl, vr( 1, i ), 1 )
655 CALL dscal( n, scl, vr( 1, i+1 ), 1 )
657 work( k ) = vr( k, i )**2 + vr( k, i+1 )**2
659 k = idamax( n, work, 1 )
660 CALL dlartg( vr( k, i ), vr( k, i+1 ), cs, sn, r )
661 CALL drot( n, vr( 1, i ), 1, vr( 1, i+1 ), 1, cs, sn )
671 CALL dlascl(
'G', 0, 0, cscale, anrm, n-info, 1, wr( info+1 ),
672 $
max( n-info, 1 ), ierr )
673 CALL dlascl(
'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 dlascl(
'G', 0, 0, cscale, anrm, n, 1, rcondv, n,
680 CALL dlascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, wr, n,
682 CALL dlascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, wi, n,