260 SUBROUTINE dtrsna( 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 DOUBLE PRECISION S( * ), SEP( * ), T( LDT, * ), VL( LDVL, * ),
277 $ vr( ldvr, * ), work( ldwork, * )
283 DOUBLE PRECISION ZERO, ONE, TWO
284 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0, two = 2.0d+0 )
287 LOGICAL PAIR, SOMCON, WANTBH, WANTS, WANTSP
288 INTEGER I, IERR, IFST, ILST, J, K, KASE, KS, N2, NN
289 DOUBLE PRECISION BIGNUM, COND, CS, DELTA, DUMM, EPS, EST, LNRM,
290 $ mu, prod, prod1, prod2, rnrm, scale, smlnum, sn
294 DOUBLE PRECISION DUMMY( 1 )
298 DOUBLE PRECISION DDOT, DLAMCH, DLAPY2, DNRM2
299 EXTERNAL LSAME, DDOT, DLAMCH, DLAPY2, DNRM2
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(
'DTRSNA', -info )
380 IF( .NOT.
SELECT( 1 ) )
386 $ sep( 1 ) = abs( t( 1, 1 ) )
393 smlnum = dlamch(
'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 = ddot( n, vr( 1, ks ), 1, vl( 1, ks ), 1 )
435 rnrm = dnrm2( n, vr( 1, ks ), 1 )
436 lnrm = dnrm2( n, vl( 1, ks ), 1 )
437 s( ks ) = abs( prod ) / ( rnrm*lnrm )
442 prod1 = ddot( n, vr( 1, ks ), 1, vl( 1, ks ), 1 )
443 prod1 = prod1 + ddot( n, vr( 1, ks+1 ), 1, vl( 1,
446 prod2 = ddot( n, vl( 1, ks ), 1, vr( 1, ks+1 ), 1 )
447 prod2 = prod2 - ddot( n, vl( 1, ks+1 ), 1, vr( 1,
450 rnrm = dlapy2( dnrm2( n, vr( 1, ks ), 1 ),
451 $ dnrm2( n, vr( 1, ks+1 ), 1 ) )
452 lnrm = dlapy2( dnrm2( n, vl( 1, ks ), 1 ),
453 $ dnrm2( n, vl( 1, ks+1 ), 1 ) )
454 cond = dlapy2( prod1, prod2 ) / ( rnrm*lnrm )
468 CALL dlacpy(
'Full', n, n, t, ldt, work, ldwork )
471 CALL dtrexc(
'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 = dlapy2( 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 dlacn2( nn, work( 1, n+2 ), work( 1, n+4 ),
549 CALL dlaqtr( .true., .true., n-1, work( 2,
551 $ ldwork, dummy, dumm, scale,
552 $ work( 1, n+4 ), work( 1, n+6 ),
559 CALL dlaqtr( .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 dlaqtr( .false., .true., n-1, work( 2,
572 $ ldwork, dummy, dumm, scale,
573 $ work( 1, n+4 ), work( 1, n+6 ),
580 CALL dlaqtr( .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 )