1 SUBROUTINE pztrevc( SIDE, HOWMNY, SELECT, N, T, DESCT, VL, DESCVL,
2 $ VR, DESCVR, MM, M, WORK, RWORK, INFO )
10 CHARACTER HOWMNY, SIDE
11 INTEGER INFO, M, MM, N
15 INTEGER DESCT( * ), DESCVL( * ), DESCVR( * )
16 DOUBLE PRECISION RWORK( * )
17 COMPLEX*16 T( * ), VL( * ), VR( * ), WORK( * )
204 DOUBLE PRECISION ZERO, ONE
205 parameter( zero = 0.0d+0, one = 1.0d+0 )
206 COMPLEX*16 CZERO, CONE
207 parameter( czero = ( 0.0d+0, 0.0d+0 ),
208 $ cone = ( 1.0d+0, 0.0d+0 ) )
209 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
210 $ mb_, nb_, rsrc_, csrc_, lld_
211 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
212 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
213 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
216 LOGICAL ALLV, BOTHV, LEFTV, OVER, RIGHTV, SOMEV
217 INTEGER CONTXT, CSRC, I, ICOL, II, IROW, IS, ITMP1,
218 $ itmp2, j, k, ki, ldt, ldvl, ldvr, ldw, mb,
219 $ mycol, myrow, nb, npcol, nprow, rsrc
221 DOUBLE PRECISION OVFL, REMAXD, SCALE, SMIN, SMLNUM, ULP, UNFL
222 COMPLEX*16 CDUM, REMAXC, SHIFT
225 INTEGER DESCW( DLEN_ )
229 DOUBLE PRECISION PDLAMCH
230 EXTERNAL lsame, pdlamch
233 EXTERNAL blacs_gridinfo,
descinit, dgsum2d, igamn2d,
239 INTRINSIC abs, dble, dcmplx, dconjg, dimag,
max
242 DOUBLE PRECISION CABS1
245 cabs1( cdum ) = abs( dble( cdum ) ) + abs( dimag( cdum ) )
250 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
253 contxt = desct( ctxt_ )
254 rsrc = desct( rsrc_ )
255 csrc = desct( csrc_ )
260 ldvr = descvr( lld_ )
261 ldvl = descvl( lld_ )
263 CALL blacs_gridinfo( contxt, nprow, npcol, myrow, mycol )
264 self = myrow*npcol + mycol
268 bothv = lsame( side,
'B' )
269 rightv = lsame( side,
'R' ) .OR. bothv
270 leftv = lsame( side,
'L' ) .OR. bothv
272 allv = lsame( howmny,
'A' )
273 over = lsame( howmny,
'B' ) .OR. lsame( howmny,
'O' )
274 somev = lsame( howmny,
'S' )
290 IF( .NOT.rightv .AND. .NOT.leftv )
THEN
292 ELSE IF( .NOT.allv .AND. .NOT.over .AND. .NOT.somev )
THEN
294 ELSE IF( n.LT.0 )
THEN
296 ELSE IF( mm.LT.m )
THEN
299 CALL igamn2d( contxt,
'ALL',
' ', 1, 1, info, 1, itmp1, itmp2, -1,
302 CALL pxerbla( contxt,
'PZTREVC', -info )
313 unfl = pdlamch( contxt,
'Safe minimum' )
315 CALL pdlabad( contxt, unfl, ovfl )
316 ulp = pdlamch( contxt,
'Precision' )
317 smlnum = unfl*( n / ulp )
322 CALL infog2l( i, i, desct, nprow, npcol, myrow, mycol, irow,
323 $ icol, itmp1, itmp2 )
324 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
325 work( ldw+irow ) = t( ( icol-1 )*ldt+irow )
335 CALL pdzasum( j-1, rwork( j ), t, 1, j, desct, 1 )
339 CALL dgsum2d( contxt,
'Row',
' ', n, 1, rwork, n, -1, -1 )
347 CALL descinit( descw, n, 1, nb, 1, rsrc, csrc, contxt, ldw,
354 IF( .NOT.
SELECT( ki ) )
360 CALL infog2l( ki, ki, desct, nprow, npcol, myrow, mycol,
361 $ irow, icol, itmp1, itmp2 )
362 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
363 shift = t( ( icol-1 )*ldt+irow )
364 smin =
max( ulp*( cabs1( shift ) ), smlnum )
366 CALL dgsum2d( contxt,
'ALL',
' ', 1, 1, smin, 1, -1, -1 )
367 CALL zgsum2d( contxt,
'ALL',
' ', 1, 1, shift, 1, -1, -1 )
369 CALL infog2l( 1, 1, descw, nprow, npcol, myrow, mycol, irow,
370 $ icol, itmp1, itmp2 )
371 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
379 CALL pzcopy( ki-1, t, 1, ki, desct, 1, work, 1, 1, descw,
383 CALL infog2l( k, 1, descw, nprow, npcol, myrow, mycol,
384 $ irow, icol, itmp1, itmp2 )
385 IF( myrow.EQ.itmp1 .AND. mycol.EQ.itmp2 )
THEN
386 work( irow ) = -work( irow )
394 CALL infog2l( k, k, desct, nprow, npcol, myrow, mycol,
395 $ irow, icol, itmp1, itmp2 )
396 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
397 t( ( icol-1 )*ldt+irow ) = t( ( icol-1 )*ldt+irow ) -
399 IF( cabs1( t( ( icol-1 )*ldt+irow ) ).LT.smin )
THEN
400 t( ( icol-1 )*ldt+irow ) = dcmplx( smin )
406 CALL pzlattrs(
'Upper',
'No transpose',
'Non-unit',
'Y',
407 $ ki-1, t, 1, 1, desct, work, 1, 1, descw,
408 $ scale, rwork, info )
409 CALL infog2l( ki, 1, descw, nprow, npcol, myrow, mycol,
410 $ irow, icol, itmp1, itmp2 )
411 IF( myrow.EQ.itmp1 .AND. mycol.EQ.itmp2 )
THEN
412 work( irow ) = dcmplx( scale )
419 CALL pzcopy( ki, work, 1, 1, descw, 1, vr, 1, is, descvr,
422 CALL pzamax( ki, remaxc, ii, vr, 1, is, descvr, 1 )
423 remaxd = one /
max( cabs1( remaxc ), unfl )
424 CALL pzdscal( ki, remaxd, vr, 1, is, descvr, 1 )
426 CALL pzlaset(
' ', n-ki, 1, czero, czero, vr, ki+1, is,
430 $
CALL pzgemv(
'N', n, ki-1, cone, vr, 1, 1, descvr,
431 $ work, 1, 1, descw, 1, dcmplx( scale ),
432 $ vr, 1, ki, descvr, 1 )
434 CALL pzamax( n, remaxc, ii, vr, 1, ki, descvr, 1 )
435 remaxd = one /
max( cabs1( remaxc ), unfl )
436 CALL pzdscal( n, remaxd, vr, 1, ki, descvr, 1 )
442 CALL infog2l( k, k, desct, nprow, npcol, myrow, mycol,
443 $ irow, icol, itmp1, itmp2 )
444 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
445 t( ( icol-1 )*ldt+irow ) = work( ldw+irow )
459 CALL descinit( descw, n, 1, mb, 1, rsrc, csrc, contxt, ldw,
466 IF( .NOT.
SELECT( ki ) )
472 CALL infog2l( ki, ki, desct, nprow, npcol, myrow, mycol,
473 $ irow, icol, itmp1, itmp2 )
474 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
475 shift = t( ( icol-1 )*ldt+irow )
476 smin =
max( ulp*( cabs1( shift ) ), smlnum )
478 CALL dgsum2d( contxt,
'ALL',
' ', 1, 1, smin, 1, -1, -1 )
479 CALL zgsum2d( contxt,
'ALL',
' ', 1, 1, shift, 1, -1, -1 )
481 CALL infog2l( n, 1, descw, nprow, npcol, myrow, mycol, irow,
482 $ icol, itmp1, itmp2 )
483 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
490 CALL pzcopy( n-ki, t, ki, ki+1, desct, n, work, ki+1, 1,
494 CALL infog2l( k, 1, descw, nprow, npcol, myrow, mycol,
495 $ irow, icol, itmp1, itmp2 )
496 IF( myrow.EQ.itmp1 .AND. mycol.EQ.itmp2 )
THEN
497 work( irow ) = -dconjg( work( irow ) )
505 CALL infog2l( k, k, desct, nprow, npcol, myrow, mycol,
506 $ irow, icol, itmp1, itmp2 )
507 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
508 t( ( icol-1 )*ldt+irow ) = t( ( icol-1 )*ldt+irow ) -
510 IF( cabs1( t( ( icol-1 )*ldt+irow ) ).LT.smin )
511 $ t( ( icol-1 )*ldt+irow ) = dcmplx( smin )
516 CALL pzlattrs(
'Upper',
'Conjugate transpose',
'Nonunit',
517 $
'Y', n-ki, t, ki+1, ki+1, desct, work,
518 $ ki+1, 1, descw, scale, rwork, info )
519 CALL infog2l( ki, 1, descw, nprow, npcol, myrow, mycol,
520 $ irow, icol, itmp1, itmp2 )
521 IF( myrow.EQ.itmp1 .AND. mycol.EQ.itmp2 )
THEN
522 work( irow ) = dcmplx( scale )
529 CALL pzcopy( n-ki+1, work, ki, 1, descw, 1, vl, ki, is,
532 CALL pzamax( n-ki+1, remaxc, ii, vl, ki, is, descvl, 1 )
533 remaxd = one /
max( cabs1( remaxc ), unfl )
534 CALL pzdscal( n-ki+1, remaxd, vl, ki, is, descvl, 1 )
536 CALL pzlaset(
' ', ki-1, 1, czero, czero, vl, 1, is,
540 $
CALL pzgemv(
'N', n, n-ki, cone, vl, 1, ki+1, descvl,
541 $ work, ki+1, 1, descw, 1, dcmplx( scale ),
542 $ vl, 1, ki, descvl, 1 )
544 CALL pzamax( n, remaxc, ii, vl, 1, ki, descvl, 1 )
545 remaxd = one /
max( cabs1( remaxc ), unfl )
546 CALL pzdscal( n, remaxd, vl, 1, ki, descvl, 1 )
552 CALL infog2l( k, k, desct, nprow, npcol, myrow, mycol,
553 $ irow, icol, itmp1, itmp2 )
554 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
555 t( ( icol-1 )*ldt+irow ) = work( ldw+irow )