378 SUBROUTINE stgsna( JOB, HOWMNY, SELECT, N, A, LDA, B, LDB, VL,
379 $ LDVL, VR, LDVR, S, DIF, MM, M, WORK, LWORK,
387 CHARACTER HOWMNY, JOB
388 INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, M, MM, N
393 REAL A( LDA, * ), B( LDB, * ), DIF( * ), S( * ),
394 $ vl( ldvl, * ), vr( ldvr, * ), work( * )
401 PARAMETER ( DIFDRI = 3 )
402 REAL ZERO, ONE, TWO, FOUR
403 parameter( zero = 0.0e+0, one = 1.0e+0, two = 2.0e+0,
407 LOGICAL LQUERY, PAIR, SOMCON, WANTBH, WANTDF, WANTS
408 INTEGER I, IERR, IFST, ILST, IZ, K, KS, LWMIN, N1, N2
409 REAL ALPHAI, ALPHAR, ALPRQT, BETA, C1, C2, COND,
410 $ eps, lnrm, rnrm, root1, root2, scale, smlnum,
411 $ tmpii, tmpir, tmpri, tmprr, uhav, uhavi, uhbv,
415 REAL DUMMY( 1 ), DUMMY1( 1 )
419 REAL SDOT, SLAMCH, SLAPY2, SNRM2
420 EXTERNAL lsame, sdot, slamch, slapy2, snrm2
426 INTRINSIC max, min, sqrt
432 wantbh = lsame( job,
'B' )
433 wants = lsame( job,
'E' ) .OR. wantbh
434 wantdf = lsame( job,
'V' ) .OR. wantbh
436 somcon = lsame( howmny,
'S' )
439 lquery = ( lwork.EQ.-1 )
441 IF( .NOT.wants .AND. .NOT.wantdf )
THEN
443 ELSE IF( .NOT.lsame( howmny,
'A' ) .AND. .NOT.somcon )
THEN
445 ELSE IF( n.LT.0 )
THEN
447 ELSE IF( lda.LT.max( 1, n ) )
THEN
449 ELSE IF( ldb.LT.max( 1, n ) )
THEN
451 ELSE IF( wants .AND. ldvl.LT.n )
THEN
453 ELSE IF( wants .AND. ldvr.LT.n )
THEN
468 IF( a( k+1, k ).EQ.zero )
THEN
473 IF(
SELECT( k ) .OR.
SELECT( k+1 ) )
488 ELSE IF( lsame( job,
'V' ) .OR. lsame( job,
'B' ) )
THEN
489 lwmin = 2*n*( n + 2 ) + 16
497 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
503 CALL xerbla(
'STGSNA', -info )
505 ELSE IF( lquery )
THEN
517 smlnum = slamch(
'S' ) / eps
530 $ pair = a( k+1, k ).NE.zero
538 IF( .NOT.
SELECT( k ) .AND. .NOT.
SELECT( k+1 ) )
541 IF( .NOT.
SELECT( k ) )
557 rnrm = slapy2( snrm2( n, vr( 1, ks ), 1 ),
558 $ snrm2( n, vr( 1, ks+1 ), 1 ) )
559 lnrm = slapy2( snrm2( n, vl( 1, ks ), 1 ),
560 $ snrm2( n, vl( 1, ks+1 ), 1 ) )
561 CALL sgemv(
'N', n, n, one, a, lda, vr( 1, ks ), 1, zero,
563 tmprr = sdot( n, work, 1, vl( 1, ks ), 1 )
564 tmpri = sdot( n, work, 1, vl( 1, ks+1 ), 1 )
565 CALL sgemv(
'N', n, n, one, a, lda, vr( 1, ks+1 ), 1,
567 tmpii = sdot( n, work, 1, vl( 1, ks+1 ), 1 )
568 tmpir = sdot( n, work, 1, vl( 1, ks ), 1 )
570 uhavi = tmpir - tmpri
571 CALL sgemv(
'N', n, n, one, b, ldb, vr( 1, ks ), 1, zero,
573 tmprr = sdot( n, work, 1, vl( 1, ks ), 1 )
574 tmpri = sdot( n, work, 1, vl( 1, ks+1 ), 1 )
575 CALL sgemv(
'N', n, n, one, b, ldb, vr( 1, ks+1 ), 1,
577 tmpii = sdot( n, work, 1, vl( 1, ks+1 ), 1 )
578 tmpir = sdot( n, work, 1, vl( 1, ks ), 1 )
580 uhbvi = tmpir - tmpri
581 uhav = slapy2( uhav, uhavi )
582 uhbv = slapy2( uhbv, uhbvi )
583 cond = slapy2( uhav, uhbv )
584 s( ks ) = cond / ( rnrm*lnrm )
591 rnrm = snrm2( n, vr( 1, ks ), 1 )
592 lnrm = snrm2( n, vl( 1, ks ), 1 )
593 CALL sgemv(
'N', n, n, one, a, lda, vr( 1, ks ), 1, zero,
595 uhav = sdot( n, work, 1, vl( 1, ks ), 1 )
596 CALL sgemv(
'N', n, n, one, b, ldb, vr( 1, ks ), 1, zero,
598 uhbv = sdot( n, work, 1, vl( 1, ks ), 1 )
599 cond = slapy2( uhav, uhbv )
600 IF( cond.EQ.zero )
THEN
603 s( ks ) = cond / ( rnrm*lnrm )
610 dif( ks ) = slapy2( a( 1, 1 ), b( 1, 1 ) )
621 work( 1 ) = a( k, k )
622 work( 2 ) = a( k+1, k )
623 work( 3 ) = a( k, k+1 )
624 work( 4 ) = a( k+1, k+1 )
625 work( 5 ) = b( k, k )
626 work( 6 ) = b( k+1, k )
627 work( 7 ) = b( k, k+1 )
628 work( 8 ) = b( k+1, k+1 )
629 CALL slag2( work, 2, work( 5 ), 2, smlnum*eps, beta,
630 $ dummy1( 1 ), alphar, dummy( 1 ), alphai )
632 c1 = two*( alphar*alphar+alphai*alphai+beta*beta )
633 c2 = four*beta*beta*alphai*alphai
634 root1 = c1 + sqrt( c1*c1-4.0*c2 )
637 cond = min( sqrt( root1 ), sqrt( root2 ) )
643 CALL slacpy(
'Full', n, n, a, lda, work, n )
644 CALL slacpy(
'Full', n, n, b, ldb, work( n*n+1 ), n )
648 CALL stgexc( .false., .false., n, work, n, work( n*n+1 ), n,
649 $ dummy, 1, dummy1, 1, ifst, ilst,
650 $ work( n*n*2+1 ), lwork-2*n*n, ierr )
666 IF( work( 2 ).NE.zero )
674 CALL stgsyl(
'N', difdri, n2, n1, work( n*n1+n1+1 ),
675 $ n, work, n, work( n1+1 ), n,
676 $ work( n*n1+n1+i ), n, work( i ), n,
677 $ work( n1+i ), n, scale, dif( ks ),
678 $ work( iz+1 ), lwork-2*n*n, iwork, ierr )
681 $ dif( ks ) = min( max( one, alprqt )*dif( ks ),
686 $ dif( ks+1 ) = dif( ks )
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine stgexc(WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z, LDZ, IFST, ILST, WORK, LWORK, INFO)
STGEXC
subroutine slag2(A, LDA, B, LDB, SAFMIN, SCALE1, SCALE2, WR1, WR2, WI)
SLAG2 computes the eigenvalues of a 2-by-2 generalized eigenvalue problem, with scaling as necessary ...
subroutine stgsna(JOB, HOWMNY, SELECT, N, A, LDA, B, LDB, VL, LDVL, VR, LDVR, S, DIF, MM, M, WORK, LWORK, IWORK, INFO)
STGSNA
subroutine stgsyl(TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D, LDD, E, LDE, F, LDF, SCALE, DIF, WORK, LWORK, IWORK, INFO)
STGSYL
subroutine sgemv(TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA, Y, INCY)
SGEMV