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
256 parameter( zero = 0.0d+0, half = 0.5d+0, one = 1.0d+0,
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, IMAX, IROW,
270 $ irowx, itmp1, itmp1x, itmp2, itmp2x, j, jfirst,
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, XJTMP, ZDUM
276 DOUBLE PRECISION XMAX( 1 )
281 DOUBLE PRECISION PDLAMCH
282 EXTERNAL lsame, idamax, pdlamch
285 EXTERNAL blacs_gridinfo, dgsum2d, dscal,
infog2l,
287 $ pzdotc, pzdotu, pzdscal,
pzlaset, pzscal,
288 $ pztrsv, zgebr2d, zgebs2d, dladiv
291 INTRINSIC abs, dble, dcmplx, dconjg, dimag,
max,
min
294 DOUBLE PRECISION CABS1, CABS2
297 cabs1( zdum ) = abs( dble( zdum ) ) + abs( dimag( zdum ) )
298 cabs2( zdum ) = abs( dble( zdum ) / 2.d0 ) +
299 $ abs( dimag( zdum ) / 2.d0 )
304 upper = lsame( uplo,
'U' )
305 notran = lsame( trans,
'N' )
306 nounit = lsame( diag,
'N' )
308 contxt = desca( ctxt_ )
309 rsrc = desca( rsrc_ )
310 csrc = desca( csrc_ )
318 IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
320 ELSE IF( .NOT.notran .AND. .NOT.lsame( trans,
'T' ) .AND. .NOT.
321 $ lsame( trans,
'C' ) )
THEN
323 ELSE IF( .NOT.nounit .AND. .NOT.lsame( diag,
'U' ) )
THEN
325 ELSE IF( .NOT.lsame( normin,
'Y' ) .AND. .NOT.
326 $ lsame( normin,
'N' ) )
THEN
328 ELSE IF( n.LT.0 )
THEN
332 CALL blacs_gridinfo( contxt, nprow, npcol, myrow, mycol )
335 CALL pxerbla( contxt,
'PZLATTRS', -info )
346 smlnum = pdlamch( contxt,
'Safe minimum' )
347 bignum = one / smlnum
348 CALL pdlabad( contxt, smlnum, bignum )
349 smlnum = smlnum / pdlamch( contxt,
'Precision' )
350 bignum = one / smlnum
354 IF( lsame( normin,
'N' ) )
THEN
364 CALL pdzasum( j-1, cnorm( j ), a, ia, ja+j-1, desca, 1 )
371 CALL pdzasum( n-j, cnorm( j ), a, ia+j, ja+j-1, desca,
376 CALL dgsum2d( contxt,
'Row',
' ', n, 1, cnorm, 1, -1, -1 )
382 imax = idamax( n, cnorm, 1 )
384 IF( tmax.LE.bignum*half )
THEN
387 tscal = half / ( smlnum*tmax )
388 CALL dscal( n, tscal, cnorm, 1 )
395 CALL pzamax( n, zdum, imax, x, ix, jx, descx, 1 )
396 xmax( 1 ) = cabs2( zdum )
397 CALL dgsum2d( contxt,
'Row',
' ', 1, 1, xmax, 1, -1, -1 )
414 IF( tscal.NE.one )
THEN
426 grow = half /
max( xbnd, smlnum )
428 DO 30 j = jfirst, jlast, jinc
436 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol, myrow,
437 $ mycol, irow, icol, itmp1, itmp2 )
438 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
439 tjjs = a( ( icol-1 )*lda+irow )
440 CALL zgebs2d( contxt,
'All',
' ', 1, 1, tjjs, 1 )
442 CALL zgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
447 IF( tjj.GE.smlnum )
THEN
451 xbnd =
min( xbnd,
min( one, tjj )*grow )
459 IF( tjj+cnorm( j ).GE.smlnum )
THEN
463 grow = grow*( tjj / ( tjj+cnorm( j ) ) )
478 grow =
min( one, half /
max( xbnd, smlnum ) )
479 DO 40 j = jfirst, jlast, jinc
488 grow = grow*( one / ( one+cnorm( j ) ) )
507 IF( tscal.NE.one )
THEN
519 grow = half /
max( xbnd, smlnum )
521 DO 60 j = jfirst, jlast, jinc
530 xj = one + cnorm( j )
531 grow =
min( grow, xbnd / xj )
534 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol, myrow,
535 $ mycol, irow, icol, itmp1, itmp2 )
536 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
537 tjjs = a( ( icol-1 )*lda+irow )
538 CALL zgebs2d( contxt,
'All',
' ', 1, 1, tjjs, 1 )
540 CALL zgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
545 IF( tjj.GE.smlnum )
THEN
550 $ xbnd = xbnd*( tjj / xj )
558 grow =
min( grow, xbnd )
565 grow =
min( one, half /
max( xbnd, smlnum ) )
566 DO 70 j = jfirst, jlast, jinc
575 xj = one + cnorm( j )
582 IF( ( grow*tscal ).GT.smlnum )
THEN
587 CALL pztrsv( uplo, trans, diag, n, a, ia, ja, desca, x, ix, jx,
593 IF( xmax( 1 ).GT.bignum*half )
THEN
598 scale = ( bignum*half ) / xmax( 1 )
599 CALL pzdscal( n, scale, x, ix, jx, descx, 1 )
602 xmax( 1 ) = xmax( 1 )*two
609 DO 100 j = jfirst, jlast, jinc
614 CALL infog2l( ix+j-1, jx, descx, nprow, npcol, myrow,
615 $ mycol, irowx, icolx, itmp1x, itmp2x )
616 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
THEN
618 CALL zgebs2d( contxt,
'All',
' ', 1, 1, xjtmp, 1 )
620 CALL zgebr2d( contxt,
'All',
' ', 1, 1, xjtmp, 1,
626 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol,
627 $ myrow, mycol, irow, icol, itmp1, itmp2 )
628 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
THEN
629 tjjs = a( ( icol-1 )*lda+irow )*tscal
630 CALL zgebs2d( contxt,
'All',
' ', 1, 1, tjjs, 1 )
632 CALL zgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
641 IF( tjj.GT.smlnum )
THEN
645 IF( tjj.LT.one )
THEN
646 IF( xj.GT.tjj*bignum )
THEN
651 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
654 xmax( 1 ) = xmax( 1 )*rec
659 CALL dladiv( dble( xjtmp ), dimag( xjtmp ),
660 $ dble( tjjs ), dimag( tjjs ), zr, zi )
661 xjtmp = dcmplx( zr, zi )
663 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
667 ELSE IF( tjj.GT.zero )
THEN
671 IF( xj.GT.tjj*bignum )
THEN
676 rec = ( tjj*bignum ) / xj
677 IF( cnorm( j ).GT.one )
THEN
682 rec = rec / cnorm( j )
684 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
687 xmax( 1 ) = xmax( 1 )*rec
691 CALL dladiv( dble( xjtmp ), dimag( xjtmp ),
692 $ dble( tjjs ), dimag( tjjs ), zr, zi )
693 xjtmp = dcmplx( zr, zi )
695 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
704 CALL pzlaset(
' ', n, 1, czero, czero, x, ix, jx,
706 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
722 IF( cnorm( j ).GT.( bignum-xmax( 1 ) )*rec )
THEN
727 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
731 ELSE IF( xj*cnorm( j ).GT.( bignum-xmax( 1 ) ) )
THEN
735 CALL pzdscal( n, half, x, ix, jx, descx, 1 )
747 CALL pzaxpy( j-1, zdum, a, ia, ja+j-1, desca, 1, x,
749 CALL pzamax( j-1, zdum, imax, x, ix, jx, descx, 1 )
750 xmax( 1 ) = cabs1( zdum )
751 CALL dgsum2d( contxt,
'Row',
' ', 1, 1, xmax, 1,
761 CALL pzaxpy( n-j, zdum, a, ia+j, ja+j-1, desca, 1,
762 $ x, ix+j, jx, descx, 1 )
763 CALL pzamax( n-j, zdum, i, x, ix+j, jx, descx, 1 )
764 xmax( 1 ) = cabs1( zdum )
765 CALL dgsum2d( contxt,
'Row',
' ', 1, 1, xmax, 1,
771 ELSE IF( lsame( trans,
'T' ) )
THEN
775 DO 120 j = jfirst, jlast, jinc
781 CALL infog2l( ix+j-1, jx, descx, nprow, npcol, myrow,
782 $ mycol, irowx, icolx, itmp1x, itmp2x )
783 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
THEN
785 CALL zgebs2d( contxt,
'All',
' ', 1, 1, xjtmp, 1 )
787 CALL zgebr2d( contxt,
'All',
' ', 1, 1, xjtmp, 1,
791 uscal = dcmplx( tscal )
792 rec = one /
max( xmax( 1 ), one )
793 IF( cnorm( j ).GT.( bignum-xj )*rec )
THEN
800 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol,
801 $ myrow, mycol, irow, icol, itmp1,
803 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
805 tjjs = a( ( icol-1 )*lda+irow )*tscal
806 CALL zgebs2d( contxt,
'All',
' ', 1, 1, tjjs,
809 CALL zgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
816 IF( tjj.GT.one )
THEN
820 rec =
min( one, rec*tjj )
821 CALL dladiv( dble( uscal ), dimag( uscal ),
822 $ dble( tjjs ), dimag( tjjs ), zr, zi )
823 uscal = dcmplx( zr, zi )
825 IF( rec.LT.one )
THEN
826 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
829 xmax( 1 ) = xmax( 1 )*rec
834 IF( uscal.EQ.cone )
THEN
840 CALL pzdotu( j-1, csumj, a, ia, ja+j-1, desca, 1,
841 $ x, ix, jx, descx, 1 )
842 ELSE IF( j.LT.n )
THEN
843 CALL pzdotu( n-j, csumj, a, ia+j, ja+j-1, desca, 1,
844 $ x, ix+j, jx, descx, 1 )
846 IF( mycol.EQ.itmp2x )
THEN
847 CALL zgebs2d( contxt,
'Row',
' ', 1, 1, csumj, 1 )
849 CALL zgebr2d( contxt,
'Row',
' ', 1, 1, csumj, 1,
861 zdum = dconjg( uscal )
862 CALL pzscal( j-1, zdum, a, ia, ja+j-1, desca, 1 )
863 CALL pzdotu( j-1, csumj, a, ia, ja+j-1, desca, 1,
864 $ x, ix, jx, descx, 1 )
865 CALL dladiv( dble( zdum ), dimag( zdum ),
866 $ dble( uscal ), dimag( uscal ), zr, zi)
867 zdum = dcmplx( zr, zi )
868 CALL pzscal( j-1, zdum, a, ia, ja+j-1, desca, 1 )
869 ELSE IF( j.LT.n )
THEN
873 zdum = dconjg( uscal )
874 CALL pzscal( n-j, zdum, a, ia+j, ja+j-1, desca, 1 )
875 CALL pzdotu( n-j, csumj, a, ia+j, ja+j-1, desca, 1,
876 $ x, ix+j, jx, descx, 1 )
877 CALL dladiv( dble( zdum ), dimag( zdum ),
878 $ dble( uscal ), dimag( uscal ), zr, zi)
879 zdum = dcmplx( zr, zi )
880 CALL pzscal( n-j, zdum, a, ia+j, ja+j-1, desca, 1 )
882 IF( mycol.EQ.itmp2x )
THEN
883 CALL zgebs2d( contxt,
'Row',
' ', 1, 1, csumj, 1 )
885 CALL zgebr2d( contxt,
'Row',
' ', 1, 1, csumj, 1,
890 IF( uscal.EQ.dcmplx( tscal ) )
THEN
897 xjtmp = xjtmp - csumj
903 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol,
904 $ myrow, mycol, irow, icol, itmp1,
906 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
908 tjjs = a( ( icol-1 )*lda+irow )*tscal
909 CALL zgebs2d( contxt,
'All',
' ', 1, 1, tjjs,
912 CALL zgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
924 IF( tjj.GT.smlnum )
THEN
928 IF( tjj.LT.one )
THEN
929 IF( xj.GT.tjj*bignum )
THEN
934 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
937 xmax( 1 ) = xmax( 1 )*rec
941 CALL dladiv( dble( xjtmp ), dimag( xjtmp ),
942 $ dble( tjjs ), dimag( tjjs ), zr, zi )
943 xjtmp = dcmplx( zr, zi )
944 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
948 ELSE IF( tjj.GT.zero )
THEN
952 IF( xj.GT.tjj*bignum )
THEN
956 rec = ( tjj*bignum ) / xj
957 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
960 xmax( 1 ) = xmax( 1 )*rec
963 CALL dladiv( dble( xjtmp ), dimag( xjtmp ),
964 $ dble( tjjs ), dimag( tjjs ), zr, zi )
965 xjtmp = dcmplx( zr, zi )
966 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
975 CALL pzlaset(
' ', n, 1, czero, czero, x, ix, jx,
977 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
992 CALL dladiv( dble( xjtmp ), dimag( xjtmp ),
993 $ dble( tjjs ), dimag( tjjs ), zr, zi )
994 xjtmp = dcmplx( zr, zi )
995 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
1000 xmax( 1 ) =
max( xmax( 1 ), cabs1( xjtmp ) )
1007 DO 140 j = jfirst, jlast, jinc
1012 CALL infog2l( ix+j-1, jx, descx, nprow, npcol, myrow,
1013 $ mycol, irowx, icolx, itmp1x, itmp2x )
1014 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
THEN
1016 CALL zgebs2d( contxt,
'All',
' ', 1, 1, xjtmp, 1 )
1018 CALL zgebr2d( contxt,
'All',
' ', 1, 1, xjtmp, 1,
1023 rec = one /
max( xmax( 1 ), one )
1024 IF( cnorm( j ).GT.( bignum-xj )*rec )
THEN
1031 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol,
1032 $ myrow, mycol, irow, icol, itmp1,
1034 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
1036 tjjs = dconjg( a( ( icol-1 )*lda+irow ) )*tscal
1037 CALL zgebs2d( contxt,
'All',
' ', 1, 1, tjjs,
1040 CALL zgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
1047 IF( tjj.GT.one )
THEN
1051 rec =
min( one, rec*tjj )
1052 CALL dladiv( dble( uscal ), dimag( uscal ),
1053 $ dble( tjjs ), dimag( tjjs ), zr, zi )
1054 uscal = dcmplx( zr, zi )
1056 IF( rec.LT.one )
THEN
1057 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
1060 xmax( 1 ) = xmax( 1 )*rec
1065 IF( uscal.EQ.cone )
THEN
1071 CALL pzdotc( j-1, csumj, a, ia, ja+j-1, desca, 1,
1072 $ x, ix, jx, descx, 1 )
1073 ELSE IF( j.LT.n )
THEN
1074 CALL pzdotc( n-j, csumj, a, ia+j, ja+j-1, desca, 1,
1075 $ x, ix+j, jx, descx, 1 )
1077 IF( mycol.EQ.itmp2x )
THEN
1078 CALL zgebs2d( contxt,
'Row',
' ', 1, 1, csumj, 1 )
1080 CALL zgebr2d( contxt,
'Row',
' ', 1, 1, csumj, 1,
1093 zdum = dconjg( uscal )
1094 CALL pzscal( j-1, zdum, a, ia, ja+j-1, desca, 1 )
1095 CALL pzdotc( j-1, csumj, a, ia, ja+j-1, desca, 1,
1096 $ x, ix, jx, descx, 1 )
1097 CALL dladiv( one, zero,
1098 $ dble( zdum ), dimag( zdum ), zr, zi )
1099 zdum = dcmplx( zr, zi )
1100 CALL pzscal( j-1, zdum, a, ia, ja+j-1, desca, 1 )
1101 ELSE IF( j.LT.n )
THEN
1106 zdum = dconjg( uscal )
1107 CALL pzscal( n-j, zdum, a, ia+j, ja+j-1, desca, 1 )
1108 CALL pzdotc( n-j, csumj, a, ia+j, ja+j-1, desca, 1,
1109 $ x, ix+j, jx, descx, 1 )
1110 CALL dladiv( one, zero,
1111 $ dble( zdum ), dimag( zdum ), zr, zi )
1112 zdum = dcmplx( zr, zi )
1113 CALL pzscal( n-j, zdum, a, ia+j, ja+j-1, desca, 1 )
1115 IF( mycol.EQ.itmp2x )
THEN
1116 CALL zgebs2d( contxt,
'Row',
' ', 1, 1, csumj, 1 )
1118 CALL zgebr2d( contxt,
'Row',
' ', 1, 1, csumj, 1,
1123 IF( uscal.EQ.dcmplx( tscal ) )
THEN
1130 xjtmp = xjtmp - csumj
1136 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol,
1137 $ myrow, mycol, irow, icol, itmp1,
1139 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
1141 tjjs = dconjg( a( ( icol-1 )*lda+irow ) )*tscal
1142 CALL zgebs2d( contxt,
'All',
' ', 1, 1, tjjs,
1145 CALL zgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
1157 IF( tjj.GT.smlnum )
THEN
1161 IF( tjj.LT.one )
THEN
1162 IF( xj.GT.tjj*bignum )
THEN
1167 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
1170 xmax( 1 ) = xmax( 1 )*rec
1174 CALL dladiv( dble( xjtmp ), dimag( xjtmp ),
1175 $ dble( tjjs ), dimag( tjjs ), zr, zi )
1176 xjtmp = dcmplx( zr, zi )
1177 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
1178 $ x( irowx ) = xjtmp
1179 ELSE IF( tjj.GT.zero )
THEN
1183 IF( xj.GT.tjj*bignum )
THEN
1187 rec = ( tjj*bignum ) / xj
1188 CALL pzdscal( n, rec, x, ix, jx, descx, 1 )
1191 xmax( 1 ) = xmax( 1 )*rec
1194 CALL dladiv( dble( xjtmp ), dimag( xjtmp ),
1195 $ dble( tjjs ), dimag( tjjs ), zr, zi )
1196 xjtmp = dcmplx( zr, zi )
1197 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
1198 $ x( irowx ) = xjtmp
1204 CALL pzlaset(
' ', n, 1, czero, czero, x, ix, jx,
1206 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
1219 CALL dladiv( dble( xjtmp ), dimag( xjtmp ),
1220 $ dble( tjjs ), dimag( tjjs ), zr, zi )
1221 xjtmp = dcmplx( zr, zi )
1222 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
1223 $ x( irowx ) = xjtmp
1225 xmax( 1 ) =
max( xmax( 1 ), cabs1( xjtmp ) )
1228 scale = scale / tscal
1233 IF( tscal.NE.one )
THEN
1234 CALL dscal( n, one / tscal, cnorm, 1 )