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
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_, ,
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
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_ )
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.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) ) 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.EQ..AND..EQ.
IF( MYROWITMP1 MYCOLITMP2 ) THEN
387 WORK( IROW ) = -WORK( IROW )
395 CALL INFOG2L( K, K, DESCT, NPROW, NPCOL, MYROW, MYCOL,
396 $ IROW, ICOL, ITMP1, ITMP2 )
397.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) ) THEN
398 T( ( ICOL-1 )*LDT+IROW ) = T( ( ICOL-1 )*LDT+IROW ) -
400.LT.
IF( CABS1( T( ( ICOL-1 )*LDT+IROW ) )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.EQ..AND..EQ.
IF( MYROWITMP1 MYCOLITMP2 ) 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.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) ) THEN
447 T( ( ICOL-1 )*LDT+IROW ) = WORK( LDW+IROW )
461 CALL DESCINIT( DESCW, N, 1, MB, 1, RSRC, CSRC, CONTXT, LDW,
468.NOT.
IF( SELECT( KI ) )
474 CALL INFOG2L( KI, KI, DESCT, NPROW, NPCOL, MYROW, MYCOL,
475 $ IROW, ICOL, ITMP1, ITMP2 )
476.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) ) 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.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) ) 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.EQ..AND..EQ.
IF( MYROWITMP1 MYCOLITMP2 ) THEN
499 WORK( IROW ) = -CONJG( WORK( IROW ) )
507 CALL INFOG2L( K, K, DESCT, NPROW, NPCOL, MYROW, MYCOL,
508 $ IROW, ICOL, ITMP1, ITMP2 )
509.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) ) THEN
510 T( ( ICOL-1 )*LDT+IROW ) = T( ( ICOL-1 )*LDT+IROW ) -
512.LT.
IF( CABS1( T( ( ICOL-1 )*LDT+IROW ) )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.EQ..AND..EQ.
IF( MYROWITMP1 MYCOLITMP2 ) 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.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) ) THEN
557 T( ( ICOL-1 )*LDT+IROW ) = WORK( LDW+IROW )