260 SUBROUTINE strsna( JOB, HOWMNY, SELECT, N, T, LDT, VL, LDVL,
262 $ LDVR, S, SEP, MM, M, WORK, LDWORK, IWORK,
270 CHARACTER HOWMNY, JOB
271 INTEGER INFO, LDT, LDVL, LDVR, LDWORK, M, MM, N
276 REAL S( * ), SEP( * ), T( LDT, * ), VL( LDVL, * ),
277 $ vr( ldvr, * ), work( ldwork, * )
284 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0, two = 2.0e+0 )
287 LOGICAL PAIR, SOMCON, WANTBH, WANTS, WANTSP
288 INTEGER I, IERR, IFST, ILST, J, K, KASE, KS, N2, NN
289 REAL BIGNUM, COND, CS, DELTA, DUMM, EPS, EST, LNRM,
290 $ mu, prod, prod1, prod2, rnrm, scale, smlnum, sn
298 REAL SDOT, SLAMCH, SLAPY2, SNRM2
299 EXTERNAL LSAME, SDOT, SLAMCH, SLAPY2, SNRM2
306 INTRINSIC abs, max, sqrt
312 wantbh = lsame( job,
'B' )
313 wants = lsame( job,
'E' ) .OR. wantbh
314 wantsp = lsame( job,
'V' ) .OR. wantbh
316 somcon = lsame( howmny,
'S' )
319 IF( .NOT.wants .AND. .NOT.wantsp )
THEN
321 ELSE IF( .NOT.lsame( howmny,
'A' ) .AND. .NOT.somcon )
THEN
323 ELSE IF( n.LT.0 )
THEN
325 ELSE IF( ldt.LT.max( 1, n ) )
THEN
327 ELSE IF( ldvl.LT.1 .OR. ( wants .AND. ldvl.LT.n ) )
THEN
329 ELSE IF( ldvr.LT.1 .OR. ( wants .AND. ldvr.LT.n ) )
THEN
344 IF( t( k+1, k ).EQ.zero )
THEN
349 IF(
SELECT( k ) .OR.
SELECT( k+1 ) )
364 ELSE IF( ldwork.LT.1 .OR. ( wantsp .AND. ldwork.LT.n ) )
THEN
369 CALL xerbla(
'STRSNA', -info )
380 IF( .NOT.
SELECT( 1 ) )
386 $ sep( 1 ) = abs( t( 1, 1 ) )
393 smlnum = slamch(
'S' ) / eps
394 bignum = one / smlnum
407 $ pair = t( k+1, k ).NE.zero
415 IF( .NOT.
SELECT( k ) .AND. .NOT.
SELECT( k+1 ) )
418 IF( .NOT.
SELECT( k ) )
434 prod = sdot( n, vr( 1, ks ), 1, vl( 1, ks ), 1 )
435 rnrm = snrm2( n, vr( 1, ks ), 1 )
436 lnrm = snrm2( n, vl( 1, ks ), 1 )
437 s( ks ) = abs( prod ) / ( rnrm*lnrm )
442 prod1 = sdot( n, vr( 1, ks ), 1, vl( 1, ks ), 1 )
443 prod1 = prod1 + sdot( n, vr( 1, ks+1 ), 1, vl( 1,
446 prod2 = sdot( n, vl( 1, ks ), 1, vr( 1, ks+1 ), 1 )
447 prod2 = prod2 - sdot( n, vl( 1, ks+1 ), 1, vr( 1,
450 rnrm = slapy2( snrm2( n, vr( 1, ks ), 1 ),
451 $ snrm2( n, vr( 1, ks+1 ), 1 ) )
452 lnrm = slapy2( snrm2( n, vl( 1, ks ), 1 ),
453 $ snrm2( n, vl( 1, ks+1 ), 1 ) )
454 cond = slapy2( prod1, prod2 ) / ( rnrm*lnrm )
468 CALL slacpy(
'Full', n, n, t, ldt, work, ldwork )
471 CALL strexc(
'No Q', n, work, ldwork, dummy, 1, ifst,
473 $ work( 1, n+1 ), ierr )
475 IF( ierr.EQ.1 .OR. ierr.EQ.2 )
THEN
485 IF( work( 2, 1 ).EQ.zero )
THEN
490 work( i, i ) = work( i, i ) - work( 1, 1 )
504 mu = sqrt( abs( work( 1, 2 ) ) )*
505 $ sqrt( abs( work( 2, 1 ) ) )
506 delta = slapy2( mu, work( 2, 1 ) )
508 sn = -work( 2, 1 ) / delta
522 work( 2, j ) = cs*work( 2, j )
523 work( j, j ) = work( j, j ) - work( 1, 1 )
527 work( 1, n+1 ) = two*mu
529 work( i, n+1 ) = sn*work( 1, i+1 )
540 CALL slacn2( nn, work( 1, n+2 ), work( 1, n+4 ),
549 CALL slaqtr( .true., .true., n-1, work( 2,
551 $ ldwork, dummy, dumm, scale,
552 $ work( 1, n+4 ), work( 1, n+6 ),
559 CALL slaqtr( .true., .false., n-1, work( 2,
561 $ ldwork, work( 1, n+1 ), mu, scale,
562 $ work( 1, n+4 ), work( 1, n+6 ),
570 CALL slaqtr( .false., .true., n-1, work( 2,
572 $ ldwork, dummy, dumm, scale,
573 $ work( 1, n+4 ), work( 1, n+6 ),
580 CALL slaqtr( .false., .false., n-1,
581 $ work( 2, 2 ), ldwork,
582 $ work( 1, n+1 ), mu, scale,
583 $ work( 1, n+4 ), work( 1, n+6 ),
593 sep( ks ) = scale / max( est, smlnum )
595 $ sep( ks+1 ) = sep( ks )