1 SUBROUTINE pctrevc( 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( * )
17 COMPLEX T( * ), VL( * ), VR( * ), WORK( * )
205 parameter( zero = 0.0e+0, one = 1.0e+0 )
207 parameter( czero = ( 0.0e+0, 0.0e+0 ),
208 $ cone = ( 1.0e+0, 0.0e+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 REAL OVFL, REMAXD, SCALE, SMIN, SMLNUM, ULP, UNFL
222 COMPLEX CDUM, REMAXC, SHIFT
225 INTEGER DESCW( DLEN_ )
230 EXTERNAL lsame, pslamch
233 EXTERNAL blacs_gridinfo,
descinit, sgsum2d, igamn2d,
239 INTRINSIC abs, real,
cmplx, conjg, aimag,
max
245 cabs1( cdum ) = abs( real( cdum ) ) + abs( aimag( 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,
'PCTREVC', -info )
313 unfl = pslamch( contxt,
'Safe minimum' )
315 CALL pslabad( contxt, unfl, ovfl )
316 ulp = pslamch( 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 pscasum( j-1, rwork( j ), t, 1, j, desct, 1 )
339 CALL sgsum2d( 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 sgsum2d( contxt,
'ALL',
' ', 1, 1, smin, 1, -1, -1 )
367 CALL cgsum2d( 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 pccopy( 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 ) =
cmplx( smin )
406 CALL pclattrs(
'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 ) =
cmplx( scale )
419 CALL pccopy( ki, work, 1, 1, descw, 1, vr, 1, is, descvr,
422 CALL pcamax( ki, remaxc, ii, vr, 1, is, descvr, 1 )
423 remaxd = one /
max( cabs1( remaxc ), unfl )
424 CALL pcsscal( ki, remaxd, vr, 1, is, descvr, 1 )
426 CALL pclaset(
' ', n-ki, 1, czero, czero, vr, ki+1, is,
430 $
CALL pcgemv(
'N', n, ki-1, cone, vr, 1, 1, descvr,
431 $ work, 1, 1, descw, 1,
cmplx( scale ),
432 $ vr, 1, ki, descvr, 1 )
434 CALL pcamax( n, remaxc, ii, vr, 1, ki, descvr, 1 )
435 remaxd = one /
max( cabs1( remaxc ), unfl )
436 CALL pcsscal( 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 sgsum2d( contxt,
'ALL',
' ', 1, 1, smin, 1, -1, -1 )
479 CALL cgsum2d( 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 pccopy( 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 ) = -conjg( 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 ) =
cmplx( smin )
516 CALL pclattrs(
'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 ) =
cmplx( scale )
529 CALL pccopy( n-ki+1, work, ki, 1, descw, 1, vl, ki, is,
532 CALL pcamax( n-ki+1, remaxc, ii, vl, ki, is, descvl, 1 )
533 remaxd = one /
max( cabs1( remaxc ), unfl )
534 CALL pcsscal( n-ki+1, remaxd, vl, ki, is, descvl, 1 )
536 CALL pclaset(
' ', ki-1, 1, czero, czero, vl, 1, is,
540 $
CALL pcgemv(
'N', n, n-ki, cone, vl, 1, ki+1, descvl,
541 $ work, ki+1, 1, descw, 1,
cmplx( scale ),
542 $ vl, 1, ki, descvl, 1 )
544 CALL pcamax( n, remaxc, ii, vl, 1, ki, descvl, 1 )
545 remaxd = one /
max( cabs1( remaxc ), unfl )
546 CALL pcsscal( 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 )