1 SUBROUTINE pclattrs( UPLO, TRANS, DIAG, NORMIN, N, A, IA, JA,
2 $ DESCA, X, IX, JX, DESCX, SCALE, CNORM, INFO )
10 CHARACTER DIAG, NORMIN, TRANS, UPLO
11 INTEGER IA, INFO, IX, JA, JX, N
15 INTEGER DESCA( * ), DESCX( * )
17 COMPLEX A( * ), X( * )
255 REAL ZERO, HALF, ONE, TWO
256 parameter( zero = 0.0e+0, half = 0.5e+0, one = 1.0e+0,
259 parameter( czero = ( 0.0e+0, 0.0e+0 ),
260 $ cone = ( 1.0e+0, 0.0e+0 ) )
261 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
262 $ mb_, nb_, rsrc_, csrc_, lld_
263 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
264 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
265 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
268 LOGICAL NOTRAN, NOUNIT, UPPER
269 INTEGER CONTXT, CSRC, I, ICOL, ICOLX, IMAX, IROW,
270 $ irowx, itmp1, itmp1x, itmp2, itmp2x, j, jfirst,
271 $ jinc, jlast, lda, ldx, mb, mycol, myrow, nb,
273 REAL BIGNUM, GROW, REC, SMLNUM, TJJ, TMAX, TSCAL,
276 COMPLEX CSUMJ, TJJS, USCAL, XJTMP, ZDUM
283 EXTERNAL lsame, isamax, pslamch, cladiv
298 cabs1( zdum ) = abs( real( zdum ) ) + abs( aimag( zdum ) )
299 cabs2( zdum ) = abs( real( zdum ) / 2.e0 ) +
300 $ abs( aimag( zdum ) / 2.e0 )
305 upper = lsame( uplo,
'U' )
306 notran = lsame( trans,
'N' )
307 nounit = lsame( diag,
'N' )
309 contxt = desca( ctxt_ )
310 rsrc = desca( rsrc_ )
311 csrc = desca( csrc_ )
319 IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
321 ELSE IF( .NOT.notran .AND. .NOT.lsame( trans,
'T' ) .AND. .NOT.
322 $ lsame( trans,
'C' ) )
THEN
324 ELSE IF( .NOT.nounit .AND. .NOT.lsame( diag,
'U' ) )
THEN
326 ELSE IF( .NOT.lsame( normin,
'Y' ) .AND. .NOT.
327 $ lsame( normin,
'N' ) )
THEN
329 ELSE IF( n.LT.0 )
THEN
336 CALL pxerbla( contxt,
'PCLATTRS', -info )
347 smlnum = pslamch( contxt,
'Safe minimum' )
348 bignum = one / smlnum
349 CALL pslabad( contxt, smlnum, bignum )
350 smlnum = smlnum / pslamch( contxt,
'Precision' )
351 bignum = one / smlnum
355 IF( lsame( normin,
'N' ) )
THEN
365 CALL pscasum( j-1, cnorm( j ), a, ia, ja+j-1, desca, 1 )
372 CALL pscasum( n-j, cnorm( j ), a, ia+j, ja+j-1, desca,
377 CALL sgsum2d( contxt,
'Row',
' ', n, 1, cnorm, 1, -1, -1 )
383 imax = isamax( n, cnorm, 1 )
385 IF( tmax.LE.bignum*half )
THEN
388 tscal = half / ( smlnum*tmax )
389 CALL sscal( n, tscal, cnorm, 1 )
396 CALL pcamax( n, zdum, imax, x, ix, jx, descx, 1 )
397 xmax( 1 ) = cabs2( zdum )
398 CALL sgsum2d( contxt,
'Row',
' ', 1, 1, xmax, 1, -1, -1 )
415 IF( tscal.NE.one )
THEN
427 grow = half /
max( xbnd, smlnum )
429 DO 30 j = jfirst, jlast, jinc
437 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol, myrow,
438 $ mycol, irow, icol, itmp1, itmp2 )
439 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
440 tjjs = a( ( icol-1 )*lda+irow )
441 CALL cgebs2d( contxt,
'All',
' ', 1, 1, tjjs, 1 )
443 CALL cgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
448 IF( tjj.GE.smlnum )
THEN
452 xbnd =
min( xbnd,
min( one, tjj )*grow )
460 IF( tjj+cnorm( j ).GE.smlnum )
THEN
464 grow = grow*( tjj / ( tjj+cnorm( j ) ) )
479 grow =
min( one, half /
max( xbnd, smlnum ) )
480 DO 40 j = jfirst, jlast, jinc
489 grow = grow*( one / ( one+cnorm( j ) ) )
508 IF( tscal.NE.one )
THEN
520 grow = half /
max( xbnd, smlnum )
522 DO 60 j = jfirst, jlast, jinc
531 xj = one + cnorm( j )
532 grow =
min( grow, xbnd / xj )
535 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol, myrow,
536 $ mycol, irow, icol, itmp1, itmp2 )
537 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
538 tjjs = a( ( icol-1 )*lda+irow )
539 CALL cgebs2d( contxt,
'All',
' ', 1, 1, tjjs, 1 )
541 CALL cgebr2d( contxt, 'all
', ' ', 1, 1, tjjs, 1,
546 IF( tjj.GE.smlnum )
THEN
551 $ xbnd = xbnd*( tjj / xj )
559 grow =
min( grow, xbnd )
566 grow =
min( one, half /
max( xbnd, smlnum ) )
567 DO 70 j = jfirst, jlast, jinc
576 xj = one + cnorm( j )
583 IF( ( grow*tscal ).GT.smlnum )
THEN
588 CALL pctrsv( uplo, trans, diag, n, a, ia, ja, desca, x, ix, jx,
594 IF( xmax( 1 ).GT.bignum*half )
THEN
599 scale = ( bignum*half ) / xmax( 1 )
600 CALL pcsscal( n, scale, x, ix, jx, descx, 1 )
603 xmax( 1 ) = xmax( 1 )*two
610 DO 100 j = jfirst, jlast, jinc
615 CALL infog2l( ix+j-1, jx, descx, nprow, npcol, myrow,
616 $ mycol, irowx, icolx, itmp1x, itmp2x )
617 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
THEN
619 CALL cgebs2d( contxt,
'All',
' ', 1, 1, xjtmp, 1 )
621 CALL cgebr2d( contxt,
'All', '
', 1, 1, XJTMP, 1,
627 CALL INFOG2L( IA+J-1, JA+J-1, DESCA, NPROW, NPCOL,
628 $ MYROW, MYCOL, IROW, ICOL, ITMP1, ITMP2 )
629.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) ) THEN
630 TJJS = A( ( ICOL-1 )*LDA+IROW )*TSCAL
631 CALL CGEBS2D( CONTXT, 'all
', ' ', 1, 1, TJJS, 1 )
633 CALL CGEBR2D( CONTXT, 'all
', ' ', 1, 1, TJJS, 1,
642.GT.
IF( TJJSMLNUM ) THEN
646.LT.
IF( TJJONE ) THEN
647.GT.
IF( XJTJJ*BIGNUM ) THEN
652 CALL PCSSCAL( N, REC, X, IX, JX, DESCX, 1 )
655 XMAX( 1 ) = XMAX( 1 )*REC
660 XJTMP = CLADIV( XJTMP, TJJS )
662.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
666.GT.
ELSE IF( TJJZERO ) THEN
670.GT.
IF( XJTJJ*BIGNUM ) THEN
675 REC = ( TJJ*BIGNUM ) / XJ
676.GT.
IF( CNORM( J )ONE ) THEN
681 REC = REC / CNORM( J )
683 CALL PCSSCAL( N, REC, X, IX, JX, DESCX, 1 )
686 XMAX( 1 ) = XMAX( 1 )*REC
690 XJTMP = CLADIV( XJTMP, TJJS )
692.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
701 CALL PCLASET( ' ', N, 1, CZERO, CZERO, X, IX, JX,
703.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
719.GT.
IF( CNORM( J )( BIGNUM-XMAX( 1 ) )*REC ) THEN
724 CALL PCSSCAL( N, REC, X, IX, JX, DESCX, 1 )
728.GT.
ELSE IF( XJ*CNORM( J )( BIGNUM-XMAX( 1 ) ) ) THEN
732 CALL PCSSCAL( N, HALF, X, IX, JX, DESCX, 1 )
744 CALL PCAXPY( J-1, ZDUM, A, IA, JA+J-1, DESCA, 1, X,
746 CALL PCAMAX( J-1, ZDUM, IMAX, X, IX, JX, DESCX, 1 )
747 XMAX( 1 ) = CABS1( ZDUM )
748 CALL SGSUM2D( CONTXT, 'row
', ' ', 1, 1, XMAX, 1,
758 CALL PCAXPY( N-J, ZDUM, A, IA+J, JA+J-1, DESCA, 1,
759 $ X, IX+J, JX, DESCX, 1 )
760 CALL PCAMAX( N-J, ZDUM, I, X, IX+J, JX, DESCX, 1 )
761 XMAX( 1 ) = CABS1( ZDUM )
762 CALL SGSUM2D( CONTXT, 'row
', ' ', 1, 1, XMAX, 1,
768 ELSE IF( LSAME( TRANS, 't
' ) ) THEN
772 DO 120 J = JFIRST, JLAST, JINC
778 CALL INFOG2L( IX+J-1, JX, DESCX, NPROW, NPCOL, MYROW,
779 $ MYCOL, IROWX, ICOLX, ITMP1X, ITMP2X )
780.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) ) THEN
782 CALL CGEBS2D( CONTXT, 'all
', ' ', 1, 1, XJTMP, 1 )
784 CALL CGEBR2D( CONTXT, 'all
', ' ', 1, 1, XJTMP, 1,
788 USCAL = CMPLX( TSCAL )
789 REC = ONE / MAX( XMAX( 1 ), ONE )
790.GT.
IF( CNORM( J )( BIGNUM-XJ )*REC ) THEN
797 CALL INFOG2L( IA+J-1, JA+J-1, DESCA, NPROW, NPCOL,
798 $ MYROW, MYCOL, IROW, ICOL, ITMP1,
800.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) )
802 TJJS = A( ( ICOL-1 )*LDA+IROW )*TSCAL
803 CALL CGEBS2D( CONTXT, 'all
', ' ', 1, 1, TJJS,
806 CALL CGEBR2D( CONTXT, 'all
', ' ', 1, 1, TJJS, 1,
813.GT.
IF( TJJONE ) THEN
817 REC = MIN( ONE, REC*TJJ )
818 USCAL = CLADIV( USCAL, TJJS )
820.LT.
IF( RECONE ) THEN
821 CALL PCSSCAL( N, REC, X, IX, JX, DESCX, 1 )
824 XMAX( 1 ) = XMAX( 1 )*REC
829.EQ.
IF( USCALCONE ) THEN
835 CALL PCDOTU( J-1, CSUMJ, A, IA, JA+J-1, DESCA, 1,
836 $ X, IX, JX, DESCX, 1 )
837.LT.
ELSE IF( JN ) THEN
838 CALL PCDOTU( N-J, CSUMJ, A, IA+J, JA+J-1, DESCA, 1,
839 $ X, IX+J, JX, DESCX, 1 )
841.EQ.
IF( MYCOLITMP2X ) THEN
842 CALL CGEBS2D( CONTXT, 'row
', ' ', 1, 1, CSUMJ, 1 )
844 CALL CGEBR2D( CONTXT, 'row
', ' ', 1, 1, CSUMJ, 1,
856 ZDUM = CONJG( USCAL )
857 CALL PCSCAL( J-1, ZDUM, A, IA, JA+J-1, DESCA, 1 )
858 CALL PCDOTU( J-1, CSUMJ, A, IA, JA+J-1, DESCA, 1,
859 $ X, IX, JX, DESCX, 1 )
860 ZDUM = CLADIV( ZDUM, USCAL )
861 CALL PCSCAL( J-1, ZDUM, A, IA, JA+J-1, DESCA, 1 )
862.LT.
ELSE IF( JN ) THEN
866 ZDUM = CONJG( USCAL )
867 CALL PCSCAL( N-J, ZDUM, A, IA+J, JA+J-1, DESCA, 1 )
868 CALL PCDOTU( N-J, CSUMJ, A, IA+J, JA+J-1, DESCA, 1,
869 $ X, IX+J, JX, DESCX, 1 )
870 ZDUM = CLADIV( ZDUM, USCAL )
871 CALL PCSCAL( N-J, ZDUM, A, IA+J, JA+J-1, DESCA, 1 )
873.EQ.
IF( MYCOLITMP2X ) THEN
874 CALL CGEBS2D( CONTXT, 'row
', ' ', 1, 1, CSUMJ, 1 )
876 CALL CGEBR2D( CONTXT, 'row
', ' ', 1, 1, CSUMJ, 1,
881.EQ.
IF( USCALCMPLX( TSCAL ) ) THEN
888 XJTMP = XJTMP - CSUMJ
894 CALL INFOG2L( IA+J-1, JA+J-1, DESCA, NPROW, NPCOL,
895 $ MYROW, MYCOL, IROW, ICOL, ITMP1,
897.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) )
899 TJJS = A( ( ICOL-1 )*LDA+IROW )*TSCAL
900 CALL CGEBS2D( CONTXT, 'all
', ' ', 1, 1, TJJS,
903 CALL CGEBR2D( CONTXT, 'all
', ' ', 1, 1, TJJS, 1,
915.GT.
IF( TJJSMLNUM ) THEN
919.LT.
IF( TJJONE ) THEN
920.GT.
IF( XJTJJ*BIGNUM ) THEN
925 CALL PCSSCAL( N, REC, X, IX, JX, DESCX, 1 )
928 XMAX( 1 ) = XMAX( 1 )*REC
932 XJTMP = CLADIV( XJTMP, TJJS )
933.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
937.GT.
ELSE IF( TJJZERO ) THEN
941.GT.
IF( XJTJJ*BIGNUM ) THEN
945 REC = ( TJJ*BIGNUM ) / XJ
946 CALL PCSSCAL( N, REC, X, IX, JX, DESCX, 1 )
949 XMAX( 1 ) = XMAX( 1 )*REC
952 XJTMP = CLADIV( XJTMP, TJJS )
953.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
962 CALL PCLASET( ' ', N, 1, CZERO, CZERO, X, IX, JX,
964.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
979 XJTMP = CLADIV( XJTMP, TJJS ) - CSUMJ
980.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
985 XMAX( 1 ) = MAX( XMAX( 1 ), CABS1( XJTMP ) )
992 DO 140 J = JFIRST, JLAST, JINC
997 CALL INFOG2L( IX+J-1, JX, DESCX, NPROW, NPCOL, MYROW,
998 $ MYCOL, IROWX, ICOLX, ITMP1X, ITMP2X )
999.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) ) THEN
1001 CALL CGEBS2D( CONTXT, 'all
', ' ', 1, 1, XJTMP, 1 )
1003 CALL CGEBR2D( CONTXT, 'all
', ' ', 1, 1, XJTMP, 1,
1008 REC = ONE / MAX( XMAX( 1 ), ONE )
1009.GT.
IF( CNORM( J )( BIGNUM-XJ )*REC ) THEN
1016 CALL INFOG2L( IA+J-1, JA+J-1, DESCA, NPROW, NPCOL,
1017 $ MYROW, MYCOL, IROW, ICOL, ITMP1,
1019.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) )
1021 TJJS = CONJG( A( ( ICOL-1 )*LDA+IROW ) )*TSCAL
1022 CALL CGEBS2D( CONTXT, 'all
', ' ', 1, 1, TJJS,
1025 CALL CGEBR2D( CONTXT, 'all
', ' ', 1, 1, TJJS, 1,
1032.GT.
IF( TJJONE ) THEN
1036 REC = MIN( ONE, REC*TJJ )
1037 USCAL = CLADIV( USCAL, TJJS )
1039.LT.
IF( RECONE ) THEN
1040 CALL PCSSCAL( N, REC, X, IX, JX, DESCX, 1 )
1043 XMAX( 1 ) = XMAX( 1 )*REC
1048.EQ.
IF( USCALCONE ) THEN
1054 CALL PCDOTC( J-1, CSUMJ, A, IA, JA+J-1, DESCA, 1,
1055 $ X, IX, JX, DESCX, 1 )
1056.LT.
ELSE IF( JN ) THEN
1057 CALL PCDOTC( N-J, CSUMJ, A, IA+J, JA+J-1, DESCA, 1,
1058 $ X, IX+J, JX, DESCX, 1 )
1060.EQ.
IF( MYCOLITMP2X ) THEN
1061 CALL CGEBS2D( CONTXT, 'row
', ' ', 1, 1, CSUMJ, 1 )
1063 CALL CGEBR2D( CONTXT, 'row
', ' ', 1, 1, CSUMJ, 1,
1076 ZDUM = CONJG( USCAL )
1077 CALL PCSCAL( J-1, ZDUM, A, IA, JA+J-1, DESCA, 1 )
1078 CALL PCDOTC( J-1, CSUMJ, A, IA, JA+J-1, DESCA, 1,
1079 $ X, IX, JX, DESCX, 1 )
1080 ZDUM = CLADIV( CONE, ZDUM )
1081 CALL PCSCAL( J-1, ZDUM, A, IA, JA+J-1, DESCA, 1 )
1082.LT.
ELSE IF( JN ) THEN
1087 ZDUM = CONJG( USCAL )
1088 CALL PCSCAL( N-J, ZDUM, A, IA+J, JA+J-1, DESCA, 1 )
1089 CALL PCDOTC( N-J, CSUMJ, A, IA+J, JA+J-1, DESCA, 1,
1090 $ X, IX+J, JX, DESCX, 1 )
1091 ZDUM = CLADIV( CONE, ZDUM )
1092 CALL PCSCAL( N-J, ZDUM, A, IA+J, JA+J-1, DESCA, 1 )
1094.EQ.
IF( MYCOLITMP2X ) THEN
1095 CALL CGEBS2D( CONTXT, 'row
', ' ', 1, 1, CSUMJ, 1 )
1097 CALL CGEBR2D( CONTXT, 'row
', ' ', 1, 1, CSUMJ, 1,
1102.EQ.
IF( USCALCMPLX( TSCAL ) ) THEN
1109 XJTMP = XJTMP - CSUMJ
1115 CALL INFOG2L( IA+J-1, JA+J-1, DESCA, NPROW, NPCOL,
1116 $ MYROW, MYCOL, IROW, ICOL, ITMP1,
1118.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) )
1120 TJJS = CONJG( A( ( ICOL-1 )*LDA+IROW ) )*TSCAL
1121 CALL CGEBS2D( CONTXT, 'all
', ' ', 1, 1, TJJS,
1124 CALL CGEBR2D( CONTXT, 'all
', ' ', 1, 1, TJJS, 1,
1136.GT.
IF( TJJSMLNUM ) THEN
1140.LT.
IF( TJJONE ) THEN
1141.GT.
IF( XJTJJ*BIGNUM ) THEN
1146 CALL PCSSCAL( N, REC, X, IX, JX, DESCX, 1 )
1149 XMAX( 1 ) = XMAX( 1 )*REC
1153 XJTMP = CLADIV( XJTMP, TJJS )
1154.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
1155 $ X( IROWX ) = XJTMP
1156.GT.
ELSE IF( TJJZERO ) THEN
1160.GT.
IF( XJTJJ*BIGNUM ) THEN
1164 REC = ( TJJ*BIGNUM ) / XJ
1165 CALL PCSSCAL( N, REC, X, IX, JX, DESCX, 1 )
1168 XMAX( 1 ) = XMAX( 1 )*REC
1171 XJTMP = CLADIV( XJTMP, TJJS )
1172.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
1173 $ X( IROWX ) = XJTMP
1179 CALL PCLASET( ' ', N, 1, CZERO, CZERO, X, IX, JX,
1181.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
1194 XJTMP = CLADIV( XJTMP, TJJS ) - CSUMJ
1195.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
1196 $ X( IROWX ) = XJTMP
1198 XMAX( 1 ) = MAX( XMAX( 1 ), CABS1( XJTMP ) )
1201 SCALE = SCALE / TSCAL
1206.NE.
IF( TSCALONE ) THEN
1207 CALL SSCAL( N, ONE / TSCAL, CNORM, 1 )