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