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, SMLNUM, ULP, UNFL
222 COMPLEX CDUM, REMAXC, SHIFT
225 INTEGER DESCW( DLEN_ )
231 EXTERNAL lsame, pslamch
234 EXTERNAL blacs_gridinfo,
descinit, sgsum2d, igamn2d,
240 INTRINSIC abs, real,
cmplx, conjg, aimag,
max
246 cabs1( cdum ) = abs( real( cdum ) ) + abs( aimag( cdum ) )
251 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
254 contxt = desct( ctxt_ )
255 rsrc = desct( rsrc_ )
256 csrc = desct( csrc_ )
261 ldvr = descvr( lld_ )
262 ldvl = descvl( lld_ )
264 CALL blacs_gridinfo( contxt, nprow, npcol, myrow, mycol )
265 self = myrow*npcol + mycol
269 bothv = lsame( side,
'B' )
270 rightv = lsame( side,
'R' ) .OR. bothv
271 leftv = lsame( side,
'L' ) .OR. bothv
273 allv = lsame( howmny,
'A' )
274 over = lsame( howmny,
'B' ) .OR. lsame( howmny,
'O' )
275 somev = lsame( howmny,
'S' )
291 IF( .NOT.rightv .AND. .NOT.leftv )
THEN
293 ELSE IF( .NOT.allv .AND. .NOT.over .AND. .NOT.somev )
THEN
295 ELSE IF( n.LT.0 )
THEN
297 ELSE IF( mm.LT.m )
THEN
300 CALL igamn2d( contxt,
'ALL',
' ', 1, 1, info, 1, itmp1, itmp2, -1,
303 CALL pxerbla( contxt,
'PCTREVC', -info )
314 unfl = pslamch( contxt,
'Safe minimum' )
316 CALL pslabad( contxt, unfl, ovfl )
317 ulp = pslamch( contxt,
'Precision' )
318 smlnum = unfl*( n / ulp )
323 CALL infog2l( i, i, desct, nprow, npcol, myrow, mycol, irow,
324 $ icol, itmp1, itmp2 )
325 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
326 work( ldw+irow ) = t( ( icol-1 )*ldt+irow )
336 CALL pscasum( j-1, rwork( j ), t, 1, j, desct, 1 )
340 CALL sgsum2d( contxt,
'Row',
' ', n, 1, rwork, n, -1, -1 )
348 CALL descinit( descw, n, 1, nb, 1, rsrc, csrc, contxt, ldw,
355 IF( .NOT.
SELECT( ki ) )
361 CALL infog2l( ki, ki, desct, nprow, npcol, myrow, mycol,
362 $ irow, icol, itmp1, itmp2 )
363 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
364 shift = t( ( icol-1 )*ldt+irow )
365 smin( 1 ) =
max( ulp*( cabs1( shift ) ), smlnum )
367 CALL sgsum2d( contxt,
'ALL',
' ', 1, 1, smin, 1, -1, -1 )
368 CALL cgsum2d( contxt,
'ALL',
' ', 1, 1, shift, 1, -1, -1 )
370 CALL infog2l( 1, 1, descw, nprow, npcol, myrow, mycol, irow,
371 $ icol, itmp1, itmp2 )
372 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
380 CALL pccopy( ki-1, t, 1, ki, desct, 1, work, 1, 1, descw,
384 CALL infog2l( k, 1, descw, nprow, npcol, myrow, mycol,
385 $ irow, icol, itmp1, itmp2 )
386 IF( myrow.EQ.itmp1 .AND. mycol.EQ.itmp2 )
THEN
387 work( irow ) = -work( irow )
395 CALL infog2l( k, k, desct, nprow, npcol, myrow, mycol,
396 $ irow, icol, itmp1, itmp2 )
397 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
398 t( ( icol-1 )*ldt+irow ) = t( ( icol-1 )*ldt+irow ) -
400 IF( cabs1( t( ( icol-1 )*ldt+irow ) ).LT.smin( 1 ) )
402 t( ( icol-1 )*ldt+irow ) =
cmplx( smin( 1 ) )
408 CALL pclattrs(
'Upper',
'No transpose',
'Non-unit',
'Y',
409 $ ki-1, t, 1, 1, desct, work, 1, 1, descw,
410 $ scale, rwork, info )
411 CALL infog2l( ki, 1, descw, nprow, npcol, myrow, mycol,
412 $ irow, icol, itmp1, itmp2 )
413 IF( myrow.EQ.itmp1 .AND. mycol.EQ.itmp2 )
THEN
414 work( irow ) =
cmplx( scale )
421 CALL pccopy( ki, work, 1, 1, descw, 1, vr, 1, is, descvr,
424 CALL pcamax( ki, remaxc, ii, vr, 1, is, descvr, 1 )
425 remaxd = one /
max( cabs1( remaxc ), unfl )
426 CALL pcsscal( ki, remaxd, vr, 1, is, descvr, 1 )
428 CALL pclaset(
' ', n-ki, 1, czero, czero, vr, ki+1, is,
432 $
CALL pcgemv(
'N', n, ki-1, cone, vr, 1, 1, descvr,
433 $ work, 1, 1, descw, 1,
cmplx( scale ),
434 $ vr, 1, ki, descvr, 1 )
436 CALL pcamax( n, remaxc, ii, vr, 1, ki, descvr, 1 )
437 remaxd = one /
max( cabs1( remaxc ), unfl )
438 CALL pcsscal( n, remaxd, vr, 1, ki, descvr, 1 )
444 CALL infog2l( k, k, desct, nprow, npcol, myrow, mycol,
445 $ irow, icol, itmp1, itmp2 )
446 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
447 t( ( icol-1 )*ldt+irow ) = work( ldw+irow )
461 CALL descinit( descw, n, 1, mb, 1, rsrc, csrc, contxt, ldw,
468 IF( .NOT.
SELECT( ki ) )
474 CALL infog2l( ki, ki, desct, nprow, npcol, myrow, mycol,
475 $ irow, icol, itmp1, itmp2 )
476 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
477 shift = t( ( icol-1 )*ldt+irow )
478 smin( 1 ) =
max( ulp*( cabs1( shift ) ), smlnum )
480 CALL sgsum2d( contxt,
'ALL',
' ', 1, 1, smin, 1, -1, -1 )
481 CALL cgsum2d( contxt,
'ALL',
' ', 1, 1, shift, 1, -1, -1 )
483 CALL infog2l( n, 1, descw, nprow, npcol, myrow, mycol, irow,
484 $ icol, itmp1, itmp2 )
485 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
492 CALL pccopy( n-ki, t, ki, ki+1, desct, n, work, ki+1, 1,
496 CALL infog2l( k, 1, descw, nprow, npcol, myrow, mycol,
497 $ irow, icol, itmp1, itmp2 )
498 IF( myrow.EQ.itmp1 .AND. mycol.EQ.itmp2 )
THEN
499 work( irow ) = -conjg( work( irow ) )
507 CALL infog2l( k, k, desct, nprow, npcol, myrow, mycol,
508 $ irow, icol, itmp1, itmp2 )
509 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
510 t( ( icol-1 )*ldt+irow ) = t( ( icol-1 )*ldt+irow ) -
512 IF( cabs1( t( ( icol-1 )*ldt+irow ) ).LT.smin( 1 ) )
513 $ t( ( icol-1 )*ldt+irow ) =
cmplx( smin( 1 ) )
518 CALL pclattrs(
'Upper',
'Conjugate transpose',
'Nonunit',
519 $
'Y', n-ki, t, ki+1, ki+1, desct, work,
520 $ ki+1, 1, descw, scale, rwork, info )
521 CALL infog2l( ki, 1, descw, nprow, npcol, myrow, mycol,
522 $ irow, icol, itmp1, itmp2 )
523 IF( myrow.EQ.itmp1 .AND. mycol.EQ.itmp2 )
THEN
524 work( irow ) =
cmplx( scale )
531 CALL pccopy( n-ki+1, work, ki, 1, descw, 1, vl, ki, is,
534 CALL pcamax( n-ki+1, remaxc, ii, vl, ki, is, descvl, 1 )
535 remaxd = one /
max( cabs1( remaxc ), unfl )
536 CALL pcsscal( n-ki+1, remaxd, vl, ki, is, descvl, 1 )
538 CALL pclaset(
' ', ki-1, 1, czero, czero, vl, 1, is,
542 $
CALL pcgemv(
'N', n, n-ki, cone, vl, 1, ki+1, descvl,
543 $ work, ki+1, 1, descw, 1,
cmplx( scale ),
544 $ vl, 1, ki, descvl, 1 )
546 CALL pcamax( n, remaxc, ii, vl, 1, ki, descvl, 1 )
547 remaxd = one /
max( cabs1( remaxc ), unfl )
548 CALL pcsscal( n, remaxd, vl, 1, ki, descvl, 1 )
554 CALL infog2l( k, k, desct, nprow, npcol, myrow, mycol,
555 $ irow, icol, itmp1, itmp2 )
556 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
557 t( ( icol-1 )*ldt+irow ) = work( ldw+irow )