1 SUBROUTINE pzlattrs( 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
12 DOUBLE PRECISION SCALE
15 INTEGER DESCA( * ), DESCX( * )
16 DOUBLE PRECISION CNORM( * )
17 COMPLEX*16 A( * ), X( * )
255 DOUBLE PRECISION ZERO, HALF, ONE, TWO
258 COMPLEX*16 CZERO, CONE
259 parameter( czero = ( 0.0d+0, 0.0d+0 ),
260 $ cone = ( 1.0d+0, 0.0d+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
271 $ jinc, jlast, lda, ldx, mb, mycol, myrow, nb,
273 DOUBLE PRECISION BIGNUM, GROW, REC, SMLNUM, TJJ, TMAX, TSCAL,
275 COMPLEX*16 CSUMJ, TJJS, USCAL, , ZDUM
276 DOUBLE PRECISION XMAX( 1 )
281 DOUBLE PRECISION PDLAMCH
283 EXTERNAL lsame, idamax, pdlamch, zladiv
292 INTRINSIC abs, dble, dcmplx, dconjg, dimag,
max,
min
295 DOUBLE PRECISION CABS1, CABS2
298 cabs1( zdum ) = abs( dble( zdum ) ) + abs( dimag( zdum ) )
299 cabs2( zdum ) = abs( dble( zdum ) / 2.d0 ) +
300 $ abs( dimag( zdum ) / 2.d0 )
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,
'PZLATTRS', -info )
347 smlnum = pdlamch( contxt,
'Safe minimum' )
348 bignum = one / smlnum
349 CALL pdlabad( contxt, smlnum, bignum )
350 smlnum = smlnum / pdlamch( contxt,
'Precision' )
351 bignum = one / smlnum
355 IF( lsame( normin,
'N' ) )
THEN
365 CALL pdzasum( j-1, cnorm( j ), a, ia, ja+j-1, desca, 1 )
372 CALL pdzasum( n-j, cnorm( j ), a, ia+j, ja+j-1, desca,
377 CALL dgsum2d( contxt,
'Row',
' ', n, 1, cnorm, 1, -1, -1 )
383 imax = idamax( n, cnorm, 1 )
385 IF( tmax.LE.bignum*half )
THEN
388 tscal = half / ( smlnum*tmax )
389 CALL dscal( n, tscal, cnorm, 1 )
396 CALL pzamax( n, zdum, imax, x, ix, jx, descx, 1 )
397 xmax( 1 ) = cabs2( zdum )
398 CALL dgsum2d( 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 zgebs2d( contxt,
'All',
' ', 1, 1, tjjs, 1 )
443 CALL zgebr2d( 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 zgebs2d( contxt,
'All',
' ', 1, 1, tjjs, 1 )
541 CALL zgebr2d( 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
567 DO 70 j = jfirst, jlast, jinc
576 xj = one + cnorm( j )
583 IF( ( grow*tscal ).GT.smlnum )
THEN
588 CALL pztrsv( 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 pzdscal( 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 )
619 CALL zgebs2d( contxt,
'All',
' '
621 CALL zgebr2d( 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 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
630 tjjs = a( ( icol-1 )*lda+irow )*tscal
631 CALL zgebs2d( contxt,
'All',
' ', 1, 1, tjjs, 1 )
633 CALL zgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
642 IF( tjj.GT.smlnum )
THEN
646 IF( tjj.LT.one )
THEN
647 IF( xj.GT.tjj*bignum )
THEN
652 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
655 xmax( 1 ) = xmax( 1 )*rec
660 xjtmp = zladiv( xjtmp, tjjs )
662 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
666 ELSE IF( tjj.GT.zero )
THEN
670 IF( xj.GT.tjj*bignum )
THEN
675 rec = ( tjj*bignum ) / xj
676 IF( cnorm( j ).GT.one )
THEN
681 rec = rec / cnorm( j )
683 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
686 xmax( 1 ) = xmax( 1 )*rec
690 xjtmp = zladiv( xjtmp, tjjs )
692 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
701 CALL pzlaset(
' ', n, 1, czero, czero, x, ix, jx,
703 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
719 IF( cnorm( j ).GT.( bignum-xmax( 1 ) )*rec )
THEN
724 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
728 ELSE IF( xj*cnorm( j ).GT.( bignum-xmax( 1 ) ) )
THEN
732 CALL pzdscal( n, half, x, ix, jx, descx, 1 )
744 CALL pzaxpy( j-1, zdum, a, ia, ja+j-1, desca, 1, x,
746 CALL pzamax( j-1, zdum, imax, x, ix, jx, descx, 1 )
747 xmax( 1 ) = cabs1( zdum )
748 CALL dgsum2d( contxt,
'Row',
' ', 1, 1, xmax, 1,
758 CALL pzaxpy( n-j, zdum, a, ia+j, ja+j-1, desca, 1,
759 $ x, ix+j, jx, descx, 1 )
760 CALL pzamax( n-j, zdum, i, x, ix+j, jx, descx, 1 )
761 xmax( 1 ) = cabs1( zdum )
762 CALL dgsum2d( 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 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
THEN
782 CALL zgebs2d( contxt,
'All',
' ', 1, 1, xjtmp, 1 )
784 CALL zgebr2d( contxt,
'All',
' ', 1, 1, xjtmp, 1,
788 uscal = dcmplx( tscal )
789 rec = one /
max( xmax( 1 ), one )
790 IF( cnorm( j ).GT.( bignum-xj )*rec )
THEN
797 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol,
798 $ myrow, mycol, irow, icol, itmp1,
800 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
802 tjjs = a( ( icol-1 )*lda+irow )*tscal
803 CALL zgebs2d( contxt,
'All',
' ', 1, 1, tjjs,
806 CALL zgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
813 IF( tjj.GT.one )
THEN
817 rec =
min( one, rec*tjj )
818 uscal = zladiv( uscal, tjjs )
820 IF( rec.LT.one )
THEN
821 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
824 xmax( 1 ) = xmax( 1 )*rec
829 IF( uscal.EQ.cone )
THEN
835 CALL pzdotu( j-1, csumj, a, ia, ja+j-1, desca, 1,
836 $ x, ix, jx, descx, 1 )
837 ELSE IF( j.LT.n )
THEN
838 CALL pzdotu( n-j, csumj, a, ia+j, ja+j-1, desca, 1,
839 $ x, ix+j, jx, descx, 1 )
841 IF( mycol.EQ.itmp2x )
THEN
842 CALL zgebs2d( contxt,
'Row',
' ', 1, 1, csumj, 1 )
844 CALL zgebr2d( contxt,
'Row',
' ', 1, 1, csumj, 1,
856 zdum = dconjg( uscal )
857 CALL pzscal( j-1, zdum, a, ia, ja+j-1, desca, 1 )
858 CALL pzdotu( j-1, csumj, a, ia, ja+j-1, desca, 1,
859 $ x, ix, jx, descx, 1 )
860 zdum = zladiv( zdum, uscal )
861 CALL pzscal( j-1, zdum, a, ia, ja+j-1, desca, 1 )
862 ELSE IF( j.LT.n )
THEN
866 zdum = dconjg( uscal )
867 CALL pzscal( n-j, zdum, a, ia+j, ja+j-1, desca, 1 )
868 CALL pzdotu( n-j, csumj, a, ia+j, ja+j-1, desca, 1,
869 $ x, ix+j, jx, descx, 1 )
870 zdum = zladiv( zdum, uscal )
871 CALL pzscal( n-j, zdum, a, ia+j, ja+j-1, desca, 1 )
873 IF( mycol.EQ.itmp2x )
THEN
874 CALL zgebs2d( contxt,
'Row',
' ', 1, 1, csumj, 1 )
876 CALL zgebr2d( contxt,
'Row',
' ', 1, 1, csumj, 1,
881 IF( uscal.EQ.dcmplx( 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 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
899 tjjs = a( ( icol-1 )*lda+irow )*tscal
900 CALL zgebs2d( contxt,
'All',
' ', 1, 1, tjjs,
903 CALL zgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
915 IF( tjj.GT.smlnum )
THEN
919 IF( tjj.LT.one )
THEN
920 IF( xj.GT.tjj*bignum )
THEN
925 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
928 xmax( 1 ) = xmax( 1 )*rec
932 xjtmp = zladiv( xjtmp, tjjs )
933 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
937 ELSE IF( tjj.GT.zero )
THEN
941 IF( xj.GT.tjj*bignum )
THEN
945 rec = ( tjj*bignum ) / xj
946 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
949 xmax( 1 ) = xmax( 1 )*rec
952 xjtmp = zladiv( xjtmp, tjjs )
953 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
962 CALL pzlaset(
' ', n, 1, czero, czero, x, ix, jx,
964 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
979 xjtmp = zladiv( xjtmp, tjjs ) - csumj
980 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
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
999 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
THEN
1001 CALL zgebs2d( contxt,
'All',
' ', 1, 1, xjtmp, 1 )
1003 CALL zgebr2d( contxt,
'All',
' ', 1, 1, xjtmp,
1008 rec = one /
max( xmax( 1 ), one )
1009 IF( cnorm( j ).GT.( bignum-xj )*rec )
THEN
1016 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol,
1017 $ myrow, mycol, irow, icol, itmp1,
1019 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
1021 tjjs = dconjg( a( ( icol-1 )*lda+irow ) )*tscal
1022 CALL zgebs2d( contxt,
'All',
' ', 1, 1, tjjs,
1025 CALL zgebr2d( contxt,
'All',
' ', 1,
1032 IF( tjj.GT.one )
THEN
1036 rec =
min( one, rec*tjj )
1037 uscal = zladiv( uscal, tjjs )
1039 IF( rec.LT.one )
THEN
1040 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
1043 xmax( 1 ) = xmax( 1 )*rec
1048 IF( uscal.EQ.cone )
THEN
1054 CALL pzdotc( j-1, csumj, a, ia, ja+j-1, desca, 1,
1055 $ x, ix, jx, descx, 1 )
1056 ELSE IF( j.LT.n )
THEN
1057 CALL pzdotc( n-j, csumj, a, ia+j, ja+j-1, desca, 1,
1058 $ x, ix+j, jx, descx, 1 )
1060 IF( mycol.EQ.itmp2x )
THEN
1061 CALL zgebs2d( contxt,
'Row',
' ', 1, 1, csumj, 1 )
1063 CALL zgebr2d( contxt,
'Row',
' ', 1, 1, csumj, 1,
1076 zdum = dconjg( uscal )
1077 CALL pzscal( j-1, zdum, a, ia, ja+j-1, desca, 1 )
1078 CALL pzdotc( j-1, csumj, a, ia, ja+j-1, desca, 1,
1079 $ x, ix, jx, descx, 1 )
1080 zdum = zladiv( cone, zdum )
1081 CALL pzscal( j-1, zdum, a, ia, ja+j-1, desca, 1 )
1082 ELSE IF( j.LT.n )
THEN
1087 zdum = dconjg( uscal )
1088 CALL pzscal( n-j, zdum, a, ia+j, ja+j-1, desca, 1 )
1089 CALL pzdotc( n-j, csumj, a, ia+j, ja+j-1, desca, 1,
1090 $ x, ix+j, jx, descx, 1 )
1091 zdum = zladiv( cone, zdum )
1092 CALL pzscal( n-j, zdum, a, ia+j, ja+j-1, desca, 1 )
1094 IF( mycol.EQ.itmp2x )
THEN
1095 CALL zgebs2d( contxt,
'Row',
' ', 1, 1, csumj, 1 )
1097 CALL zgebr2d( contxt,
'Row',
' ', 1, 1, csumj, 1,
1102 IF( uscal.EQ.dcmplx( 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 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
1120 tjjs = dconjg( a( ( icol-1 )*lda+irow ) )*tscal
1121 CALL zgebs2d( contxt,
'All',
' ', 1, 1, tjjs,
1124 CALL zgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
1136 IF( tjj.GT.smlnum )
THEN
1140 IF( tjj.LT.one )
THEN
1141 IF( xj.GT.tjj*bignum )
THEN
1146 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
1149 xmax( 1 ) = xmax( 1 )*rec
1153 xjtmp = zladiv( xjtmp, tjjs )
1154 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
1155 $ x( irowx ) = xjtmp
1156 ELSE IF( tjj.GT.zero )
THEN
1160 IF( xj.GT.tjj*bignum )
THEN
1164 rec = ( tjj*bignum ) / xj
1165 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
1168 xmax( 1 ) = xmax( 1 )*rec
1171 xjtmp = zladiv( xjtmp, tjjs )
1172 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
1173 $ x( irowx ) = xjtmp
1179 CALL pzlaset(
' ', n, 1, czero, czero, x, ix, jx,
1181 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
1194 xjtmp = zladiv( xjtmp, tjjs ) - csumj
1195 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
1196 $ x( irowx ) = xjtmp
1198 xmax( 1 ) =
max( xmax( 1 ), cabs1( xjtmp ) )
1201 scale = scale / tscal
1206 IF( tscal.NE.one )
THEN
1207 CALL dscal( n, one / tscal, cnorm, 1 )