235 SUBROUTINE clatrs( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X,
244 CHARACTER DIAG, NORMIN, TRANS, UPLO
250 COMPLEX A( LDA, * ), X( * )
256 REAL ZERO, HALF, ONE, TWO
257 PARAMETER ( ZERO = 0.0e+0, half = 0.5e+0, one = 1.0e+0,
261 LOGICAL NOTRAN, NOUNIT, UPPER
262 INTEGER I, IMAX, J, JFIRST, JINC, JLAST
263 REAL BIGNUM, GROW, REC, SMLNUM, TJJ, TMAX, TSCAL,
265 COMPLEX CSUMJ, TJJS, USCAL, ZDUM
269 INTEGER ICAMAX, ISAMAX
271 COMPLEX CDOTC, CDOTU, CLADIV
272 EXTERNAL lsame, icamax, isamax, scasum, slamch,
280 INTRINSIC abs, aimag, cmplx, conjg, max, min, real
286 cabs1( zdum ) = abs( real( zdum ) ) + abs( aimag( zdum ) )
287 cabs2( zdum ) = abs( real( zdum ) / 2. ) +
288 $ abs( aimag( zdum ) / 2. )
293 upper = lsame( uplo,
'U' )
294 notran = lsame( trans,
'N' )
295 nounit = lsame( diag,
'N' )
299 IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
301 ELSE IF( .NOT.notran .AND. .NOT.lsame( trans,
'T' ) .AND. .NOT.
302 $ lsame( trans,
'C' ) )
THEN
304 ELSE IF( .NOT.nounit .AND. .NOT.lsame( diag,
'U' ) )
THEN
306 ELSE IF( .NOT.lsame( normin,
'Y' ) .AND. .NOT.
307 $ lsame( normin,
'N' ) )
THEN
309 ELSE IF( n.LT.0 )
THEN
311 ELSE IF( lda.LT.max( 1, n ) )
THEN
315 CALL xerbla(
'CLATRS', -info )
327 smlnum = slamch(
'Safe minimum' ) / slamch(
'Precision' )
328 bignum = one / smlnum
330 IF( lsame( normin,
'N' ) )
THEN
339 cnorm( j ) = scasum( j-1, a( 1, j ), 1 )
346 cnorm( j ) = scasum( n-j, a( j+1, j ), 1 )
355 imax = isamax( n, cnorm, 1 )
357 IF( tmax.LE.bignum*half )
THEN
364 IF ( tmax.LE.slamch(
'Overflow') )
THEN
366 tscal = half / ( smlnum*tmax )
367 CALL sscal( n, tscal, cnorm, 1 )
381 tmax = max( tmax, abs( real( a( i, j ) ) ),
382 $ abs( aimag(a( i, j ) ) ) )
391 tmax = max( tmax, abs( real( a( i, j ) ) ),
392 $ abs( aimag(a( i, j ) ) ) )
397 IF( tmax.LE.slamch(
'Overflow') )
THEN
398 tscal = one / ( smlnum*tmax )
400 IF( cnorm( j ).LE.slamch(
'Overflow') )
THEN
401 cnorm( j ) = cnorm( j )*tscal
409 cnorm( j ) = cnorm( j ) +
410 $ tscal * cabs2( a( i, j ) )
414 cnorm( j ) = cnorm( j ) +
415 $ tscal * cabs2( a( i, j ) )
424 CALL ctrsv( uplo, trans, diag, n, a, lda, x, 1 )
435 xmax = max( xmax, cabs2( x( j ) ) )
453 IF( tscal.NE.one )
THEN
465 grow = half / max( xbnd, smlnum )
467 DO 40 j = jfirst, jlast, jinc
477 IF( tjj.GE.smlnum )
THEN
481 xbnd = min( xbnd, min( one, tjj )*grow )
489 IF( tjj+cnorm( j ).GE.smlnum )
THEN
493 grow = grow*( tjj / ( tjj+cnorm( j ) ) )
508 grow = min( one, half / max( xbnd, smlnum ) )
509 DO 50 j = jfirst, jlast, jinc
518 grow = grow*( one / ( one+cnorm( j ) ) )
537 IF( tscal.NE.one )
THEN
549 grow = half / max( xbnd, smlnum )
551 DO 70 j = jfirst, jlast, jinc
560 xj = one + cnorm( j )
561 grow = min( grow, xbnd / xj )
566 IF( tjj.GE.smlnum )
THEN
571 $ xbnd = xbnd*( tjj / xj )
579 grow = min( grow, xbnd )
586 grow = min( one, half / max( xbnd, smlnum ) )
587 DO 80 j = jfirst, jlast, jinc
596 xj = one + cnorm( j )
603 IF( ( grow*tscal ).GT.smlnum )
THEN
608 CALL ctrsv( uplo, trans, diag, n, a, lda, x, 1 )
613 IF( xmax.GT.bignum*half )
THEN
618 scale = ( bignum*half ) / xmax
619 CALL csscal( n, scale, x, 1 )
629 DO 110 j = jfirst, jlast, jinc
635 tjjs = a( j, j )*tscal
642 IF( tjj.GT.smlnum )
THEN
646 IF( tjj.LT.one )
THEN
647 IF( xj.GT.tjj*bignum )
THEN
652 CALL csscal( n, rec, x, 1 )
657 x( j ) = cladiv( x( j ), tjjs )
659 ELSE IF( tjj.GT.zero )
THEN
663 IF( xj.GT.tjj*bignum )
THEN
668 rec = ( tjj*bignum ) / xj
669 IF( cnorm( j ).GT.one )
THEN
674 rec = rec / cnorm( j )
676 CALL csscal( n, rec, x, 1 )
680 x( j ) = cladiv( x( j ), tjjs )
702 IF( cnorm( j ).GT.( bignum-xmax )*rec )
THEN
707 CALL csscal( n, rec, x, 1 )
710 ELSE IF( xj*cnorm( j ).GT.( bignum-xmax ) )
THEN
714 CALL csscal( n, half, x, 1 )
724 CALL caxpy( j-1, -x( j )*tscal, a( 1, j ), 1, x,
726 i = icamax( j-1, x, 1 )
727 xmax = cabs1( x( i ) )
735 CALL caxpy( n-j, -x( j )*tscal, a( j+1, j ), 1,
737 i = j + icamax( n-j, x( j+1 ), 1 )
738 xmax = cabs1( x( i ) )
743 ELSE IF( lsame( trans,
'T' ) )
THEN
747 DO 150 j = jfirst, jlast, jinc
754 rec = one / max( xmax, one )
755 IF( cnorm( j ).GT.( bignum-xj )*rec )
THEN
761 tjjs = a( j, j )*tscal
766 IF( tjj.GT.one )
THEN
770 rec = min( one, rec*tjj )
771 uscal = cladiv( uscal, tjjs )
773 IF( rec.LT.one )
THEN
774 CALL csscal( n, rec, x, 1 )
781 IF( uscal.EQ.cmplx( one ) )
THEN
787 csumj = cdotu( j-1, a( 1, j ), 1, x, 1 )
788 ELSE IF( j.LT.n )
THEN
789 csumj = cdotu( n-j, a( j+1, j ), 1, x( j+1 ),
798 csumj = csumj + ( a( i, j )*uscal )*x( i )
800 ELSE IF( j.LT.n )
THEN
802 csumj = csumj + ( a( i, j )*uscal )*x( i )
807 IF( uscal.EQ.cmplx( tscal ) )
THEN
812 x( j ) = x( j ) - csumj
815 tjjs = a( j, j )*tscal
825 IF( tjj.GT.smlnum )
THEN
829 IF( tjj.LT.one )
THEN
830 IF( xj.GT.tjj*bignum )
THEN
835 CALL csscal( n, rec, x, 1 )
840 x( j ) = cladiv( x( j ), tjjs )
841 ELSE IF( tjj.GT.zero )
THEN
845 IF( xj.GT.tjj*bignum )
THEN
849 rec = ( tjj*bignum ) / xj
850 CALL csscal( n, rec, x, 1 )
854 x( j ) = cladiv( x( j ), tjjs )
873 x( j ) = cladiv( x( j ), tjjs ) - csumj
875 xmax = max( xmax, cabs1( x( j ) ) )
882 DO 190 j = jfirst, jlast, jinc
889 rec = one / max( xmax, one )
890 IF( cnorm( j ).GT.( bignum-xj )*rec )
THEN
896 tjjs = conjg( a( j, j ) )*tscal
901 IF( tjj.GT.one )
THEN
905 rec = min( one, rec*tjj )
906 uscal = cladiv( uscal, tjjs )
908 IF( rec.LT.one )
THEN
909 CALL csscal( n, rec, x, 1 )
916 IF( uscal.EQ.cmplx( one ) )
THEN
922 csumj = cdotc( j-1, a( 1, j ), 1, x, 1 )
923 ELSE IF( j.LT.n )
THEN
924 csumj = cdotc( n-j, a( j+1, j ), 1, x( j+1 ),
933 csumj = csumj + ( conjg( a( i, j ) )*uscal )*
936 ELSE IF( j.LT.n )
THEN
938 csumj = csumj + ( conjg( a( i, j ) )*uscal )*
944 IF( uscal.EQ.cmplx( tscal ) )
THEN
949 x( j ) = x( j ) - csumj
952 tjjs = conjg( a( j, j ) )*tscal
962 IF( tjj.GT.smlnum )
THEN
966 IF( tjj.LT.one )
THEN
967 IF( xj.GT.tjj*bignum )
THEN
972 CALL csscal( n, rec, x, 1 )
977 x( j ) = cladiv( x( j ), tjjs )
978 ELSE IF( tjj.GT.zero )
THEN
982 IF( xj.GT.tjj*bignum )
THEN
986 rec = ( tjj*bignum ) / xj
987 CALL csscal( n, rec, x, 1 )
991 x( j ) = cladiv( x( j ), tjjs )
1010 x( j ) = cladiv( x( j ), tjjs ) - csumj
1012 xmax = max( xmax, cabs1( x( j ) ) )
1015 scale = scale / tscal
1020 IF( tscal.NE.one )
THEN
1021 CALL sscal( n, one / tscal, cnorm, 1 )