246 SUBROUTINE ztrevc3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
247 $ ldvr, mm, m, work, lwork, rwork, lrwork, info)
256 CHARACTER HOWMNY, SIDE
257 INTEGER INFO, LDT, LDVL, LDVR, LWORK, LRWORK, M, MM, N
261 DOUBLE PRECISION RWORK( * )
262 COMPLEX*16 T( ldt, * ), VL( ldvl, * ), VR( ldvr, * ),
269 DOUBLE PRECISION ZERO, ONE
270 parameter ( zero = 0.0d+0, one = 1.0d+0 )
271 COMPLEX*16 CZERO, CONE
272 parameter ( czero = ( 0.0d+0, 0.0d+0 ),
273 $ cone = ( 1.0d+0, 0.0d+0 ) )
275 parameter ( nbmin = 8, nbmax = 128 )
278 LOGICAL ALLV, BOTHV, LEFTV, LQUERY, OVER, RIGHTV, SOMEV
279 INTEGER I, II, IS, J, K, KI, IV, MAXWRK, NB
280 DOUBLE PRECISION OVFL, REMAX, SCALE, SMIN, SMLNUM, ULP, UNFL
285 INTEGER ILAENV, IZAMAX
286 DOUBLE PRECISION DLAMCH, DZASUM
287 EXTERNAL lsame, ilaenv, izamax, dlamch, dzasum
293 INTRINSIC abs, dble, dcmplx, conjg, aimag, max
296 DOUBLE PRECISION CABS1
299 cabs1( cdum ) = abs( dble( cdum ) ) + abs( aimag( cdum ) )
305 bothv = lsame( side,
'B' )
306 rightv = lsame( side,
'R' ) .OR. bothv
307 leftv = lsame( side,
'L' ) .OR. bothv
309 allv = lsame( howmny,
'A' )
310 over = lsame( howmny,
'B' )
311 somev = lsame( howmny,
'S' )
327 nb = ilaenv( 1,
'ZTREVC', side // howmny, n, -1, -1, -1 )
331 lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 )
332 IF( .NOT.rightv .AND. .NOT.leftv )
THEN
334 ELSE IF( .NOT.allv .AND. .NOT.over .AND. .NOT.somev )
THEN
336 ELSE IF( n.LT.0 )
THEN
338 ELSE IF( ldt.LT.max( 1, n ) )
THEN
340 ELSE IF( ldvl.LT.1 .OR. ( leftv .AND. ldvl.LT.n ) )
THEN
342 ELSE IF( ldvr.LT.1 .OR. ( rightv .AND. ldvr.LT.n ) )
THEN
344 ELSE IF( mm.LT.m )
THEN
346 ELSE IF( lwork.LT.max( 1, 2*n ) .AND. .NOT.lquery )
THEN
348 ELSE IF ( lrwork.LT.max( 1, n ) .AND. .NOT.lquery )
THEN
352 CALL xerbla(
'ZTREVC3', -info )
354 ELSE IF( lquery )
THEN
366 IF( over .AND. lwork .GE. n + 2*n*nbmin )
THEN
367 nb = (lwork - n) / (2*n)
368 nb = min( nb, nbmax )
369 CALL zlaset(
'F', n, 1+2*nb, czero, czero, work, n )
376 unfl = dlamch(
'Safe minimum' )
379 ulp = dlamch(
'Precision' )
380 smlnum = unfl*( n / ulp )
385 work( i ) = t( i, i )
393 rwork( j ) = dzasum( j-1, t( 1, j ), 1 )
409 IF( .NOT.
SELECT( ki ) )
412 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
417 work( ki + iv*n ) = cone
422 work( k + iv*n ) = -t( k, ki )
429 t( k, k ) = t( k, k ) - t( ki, ki )
430 IF( cabs1( t( k, k ) ).LT.smin )
435 CALL zlatrs(
'Upper',
'No transpose',
'Non-unit',
'Y',
436 $ ki-1, t, ldt, work( 1 + iv*n ), scale,
438 work( ki + iv*n ) = scale
446 CALL zcopy( ki, work( 1 + iv*n ), 1, vr( 1, is ), 1 )
448 ii = izamax( ki, vr( 1, is ), 1 )
449 remax = one / cabs1( vr( ii, is ) )
450 CALL zdscal( ki, remax, vr( 1, is ), 1 )
456 ELSE IF( nb.EQ.1 )
THEN
460 $
CALL zgemv(
'N', n, ki-1, cone, vr, ldvr,
461 $ work( 1 + iv*n ), 1, dcmplx( scale ),
464 ii = izamax( n, vr( 1, ki ), 1 )
465 remax = one / cabs1( vr( ii, ki ) )
466 CALL zdscal( n, remax, vr( 1, ki ), 1 )
473 work( k + iv*n ) = czero
479 IF( (iv.EQ.1) .OR. (ki.EQ.1) )
THEN
480 CALL zgemm(
'N',
'N', n, nb-iv+1, ki+nb-iv, cone,
482 $ work( 1 + (iv)*n ), n,
484 $ work( 1 + (nb+iv)*n ), n )
487 ii = izamax( n, work( 1 + (nb+k)*n ), 1 )
488 remax = one / cabs1( work( ii + (nb+k)*n ) )
489 CALL zdscal( n, remax, work( 1 + (nb+k)*n ), 1 )
491 CALL zlacpy(
'F', n, nb-iv+1,
492 $ work( 1 + (nb+iv)*n ), n,
493 $ vr( 1, ki ), ldvr )
503 t( k, k ) = work( k )
524 IF( .NOT.
SELECT( ki ) )
527 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
532 work( ki + iv*n ) = cone
537 work( k + iv*n ) = -conjg( t( ki, k ) )
544 t( k, k ) = t( k, k ) - t( ki, ki )
545 IF( cabs1( t( k, k ) ).LT.smin )
550 CALL zlatrs(
'Upper',
'Conjugate transpose',
'Non-unit',
551 $
'Y', n-ki, t( ki+1, ki+1 ), ldt,
552 $ work( ki+1 + iv*n ), scale, rwork, info )
553 work( ki + iv*n ) = scale
561 CALL zcopy( n-ki+1, work( ki + iv*n ), 1, vl(ki,is), 1 )
563 ii = izamax( n-ki+1, vl( ki, is ), 1 ) + ki - 1
564 remax = one / cabs1( vl( ii, is ) )
565 CALL zdscal( n-ki+1, remax, vl( ki, is ), 1 )
571 ELSE IF( nb.EQ.1 )
THEN
575 $
CALL zgemv(
'N', n, n-ki, cone, vl( 1, ki+1 ), ldvl,
576 $ work( ki+1 + iv*n ), 1, dcmplx( scale ),
579 ii = izamax( n, vl( 1, ki ), 1 )
580 remax = one / cabs1( vl( ii, ki ) )
581 CALL zdscal( n, remax, vl( 1, ki ), 1 )
589 work( k + iv*n ) = czero
595 IF( (iv.EQ.nb) .OR. (ki.EQ.n) )
THEN
596 CALL zgemm(
'N',
'N', n, iv, n-ki+iv, one,
597 $ vl( 1, ki-iv+1 ), ldvl,
598 $ work( ki-iv+1 + (1)*n ), n,
600 $ work( 1 + (nb+1)*n ), n )
603 ii = izamax( n, work( 1 + (nb+k)*n ), 1 )
604 remax = one / cabs1( work( ii + (nb+k)*n ) )
605 CALL zdscal( n, remax, work( 1 + (nb+k)*n ), 1 )
608 $ work( 1 + (nb+1)*n ), n,
609 $ vl( 1, ki-iv+1 ), ldvl )
619 t( k, k ) = work( k )
subroutine zlacpy(UPLO, M, N, A, LDA, B, LDB)
ZLACPY copies all or part of one two-dimensional array to another.
subroutine zcopy(N, ZX, INCX, ZY, INCY)
ZCOPY
subroutine zgemv(TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA, Y, INCY)
ZGEMV
subroutine zgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
ZGEMM
subroutine zlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dlabad(SMALL, LARGE)
DLABAD
subroutine zdscal(N, DA, ZX, INCX)
ZDSCAL
subroutine zlatrs(UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE, CNORM, INFO)
ZLATRS solves a triangular system of equations with the scale factor set to prevent overflow...
subroutine ztrevc3(SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, MM, M, WORK, LWORK, RWORK, LRWORK, INFO)
ZTREVC3