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.NE.
$ PAIR = A( K+1, K )ZERO
538.NOT..AND..NOT.
IF( SELECT( K ) SELECT( K+1 ) )
541.NOT.
IF( 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
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 )