246 SUBROUTINE ctrevc3( 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
262 COMPLEX T( ldt, * ), VL( ldvl, * ), VR( ldvr, * ),
270 parameter ( zero = 0.0e+0, one = 1.0e+0 )
272 parameter ( czero = ( 0.0e+0, 0.0e+0 ),
273 $ cone = ( 1.0e+0, 0.0e+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 REAL OVFL, REMAX, SCALE, SMIN, SMLNUM, ULP, UNFL
285 INTEGER ILAENV, ICAMAX
287 EXTERNAL lsame, ilaenv, icamax, slamch, scasum
293 INTRINSIC abs,
REAL, CMPLX, CONJG, AIMAG, MAX
299 cabs1( cdum ) = abs(
REAL( 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,
'CTREVC', 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(
'CTREVC3', -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 claset(
'F', n, 1+2*nb, czero, czero, work, n )
376 unfl = slamch(
'Safe minimum' )
379 ulp = slamch(
'Precision' )
380 smlnum = unfl*( n / ulp )
385 work( i ) = t( i, i )
393 rwork( j ) = scasum( 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 clatrs(
'Upper',
'No transpose',
'Non-unit',
'Y',
436 $ ki-1, t, ldt, work( 1 + iv*n ), scale,
438 work( ki + iv*n ) = scale
446 CALL ccopy( ki, work( 1 + iv*n ), 1, vr( 1, is ), 1 )
448 ii = icamax( ki, vr( 1, is ), 1 )
449 remax = one / cabs1( vr( ii, is ) )
450 CALL csscal( ki, remax, vr( 1, is ), 1 )
456 ELSE IF( nb.EQ.1 )
THEN
460 $
CALL cgemv(
'N', n, ki-1, cone, vr, ldvr,
461 $ work( 1 + iv*n ), 1, cmplx( scale ),
464 ii = icamax( n, vr( 1, ki ), 1 )
465 remax = one / cabs1( vr( ii, ki ) )
466 CALL csscal( n, remax, vr( 1, ki ), 1 )
473 work( k + iv*n ) = czero
479 IF( (iv.EQ.1) .OR. (ki.EQ.1) )
THEN
480 CALL cgemm(
'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 = icamax( n, work( 1 + (nb+k)*n ), 1 )
488 remax = one / cabs1( work( ii + (nb+k)*n ) )
489 CALL csscal( n, remax, work( 1 + (nb+k)*n ), 1 )
491 CALL clacpy(
'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 clatrs(
'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 ccopy( n-ki+1, work( ki + iv*n ), 1, vl(ki,is), 1 )
563 ii = icamax( n-ki+1, vl( ki, is ), 1 ) + ki - 1
564 remax = one / cabs1( vl( ii, is ) )
565 CALL csscal( n-ki+1, remax, vl( ki, is ), 1 )
571 ELSE IF( nb.EQ.1 )
THEN
575 $
CALL cgemv(
'N', n, n-ki, cone, vl( 1, ki+1 ), ldvl,
576 $ work( ki+1 + iv*n ), 1, cmplx( scale ),
579 ii = icamax( n, vl( 1, ki ), 1 )
580 remax = one / cabs1( vl( ii, ki ) )
581 CALL csscal( n, remax, vl( 1, ki ), 1 )
589 work( k + iv*n ) = czero
595 IF( (iv.EQ.nb) .OR. (ki.EQ.n) )
THEN
596 CALL cgemm(
'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 = icamax( n, work( 1 + (nb+k)*n ), 1 )
604 remax = one / cabs1( work( ii + (nb+k)*n ) )
605 CALL csscal( 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 slabad(SMALL, LARGE)
SLABAD
subroutine clatrs(UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE, CNORM, INFO)
CLATRS solves a triangular system of equations with the scale factor set to prevent overflow...
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine cgemv(TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA, Y, INCY)
CGEMV
subroutine claset(UPLO, M, N, ALPHA, BETA, A, LDA)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
subroutine ctrevc3(SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, MM, M, WORK, LWORK, RWORK, LRWORK, INFO)
CTREVC3
subroutine clacpy(UPLO, M, N, A, LDA, B, LDB)
CLACPY copies all or part of one two-dimensional array to another.
subroutine ccopy(N, CX, INCX, CY, INCY)
CCOPY
subroutine cgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
CGEMM
subroutine csscal(N, SA, CX, INCX)
CSSCAL