1 SUBROUTINE dlatrs( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE,
11 DOUBLE PRECISION scale
14 DOUBLE PRECISION a( lda, * ), cnorm( * ), x( * )
172 DOUBLE PRECISION zero, half, one
173 parameter( zero = 0.0d+0, half = 0.5d+0, one = 1.0d+0 )
176 LOGICAL notran, nounit, upper
177 INTEGER i, imax, j, jfirst, jinc, jlast
178 DOUBLE PRECISION bignum, grow, rec, smlnum, sumj, tjj, tjjs,
179 $ tmax, tscal, uscal, xbnd, xj, xmax
184 DOUBLE PRECISION dasum, ddot, dlamch
185 EXTERNAL lsame, idamax, dasum, ddot, dlamch
188 EXTERNAL daxpy, dscal, dtrsv,
xerbla
196 upper = lsame(
uplo,
'U' )
197 notran = lsame(
trans,
'N' )
198 nounit = lsame(
diag,
'N' )
202 IF( .NOT.upper .AND. .NOT.lsame(
uplo,
'L' ) )
THEN
204 ELSE IF( .NOT.notran .AND. .NOT.lsame(
trans,
'T' ) .AND. .NOT.
205 $ lsame(
trans,
'C' ) )
THEN
207 ELSE IF( .NOT.nounit .AND. .NOT.lsame(
diag,
'U' ) )
THEN
209 ELSE IF( .NOT.lsame( normin,
'Y' ) .AND. .NOT.
210 $ lsame( normin,
'N' ) )
THEN
212 ELSE IF( n.LT.0 )
THEN
214 ELSE IF( lda.LT.
max( 1, n ) )
THEN
218 CALL
xerbla(
'DLATRS', -info )
229 smlnum = dlamch(
'Safe minimum' ) / dlamch(
'Precision' )
230 bignum = one / smlnum
233 IF( lsame( normin,
'N' ) )
THEN
242 cnorm( j ) = dasum( j-1, a( 1, j ), 1 )
249 cnorm( j ) = dasum( n-j, a( j+1, j ), 1 )
258 imax = idamax( n, cnorm, 1 )
260 IF( tmax.LE.bignum )
THEN
263 tscal = one / ( smlnum*tmax )
264 CALL dscal( n, tscal, cnorm, 1 )
270 j = idamax( n, x, 1 )
287 IF( tscal.NE.one )
THEN
299 grow = one /
max( xbnd, smlnum )
301 DO 30 j = jfirst, jlast, jinc
310 tjj = abs( a( j, j ) )
311 xbnd =
min( xbnd,
min( one, tjj )*grow )
312 IF( tjj+cnorm( j ).GE.smlnum )
THEN
316 grow = grow*( tjj / ( tjj+cnorm( j ) ) )
331 grow =
min( one, one /
max( xbnd, smlnum ) )
332 DO 40 j = jfirst, jlast, jinc
341 grow = grow*( one / ( one+cnorm( j ) ) )
360 IF( tscal.NE.one )
THEN
372 grow = one /
max( xbnd, smlnum )
374 DO 60 j = jfirst, jlast, jinc
383 xj = one + cnorm( j )
384 grow =
min( grow, xbnd / xj )
388 tjj = abs( a( j, j ) )
390 $ xbnd = xbnd*( tjj / xj )
392 grow =
min( grow, xbnd )
399 grow =
min( one, one /
max( xbnd, smlnum ) )
400 DO 70 j = jfirst, jlast, jinc
409 xj = one + cnorm( j )
416 IF( ( grow*tscal ).GT.smlnum )
THEN
426 IF( xmax.GT.bignum )
THEN
431 scale = bignum / xmax
432 CALL dscal( n, scale, x, 1 )
440 DO 110 j = jfirst, jlast, jinc
446 tjjs = a( j, j )*tscal
453 IF( tjj.GT.smlnum )
THEN
457 IF( tjj.LT.one )
THEN
458 IF( xj.GT.tjj*bignum )
THEN
463 CALL dscal( n, rec, x, 1 )
468 x( j ) = x( j ) / tjjs
470 ELSE IF( tjj.GT.zero )
THEN
474 IF( xj.GT.tjj*bignum )
THEN
479 rec = ( tjj*bignum ) / xj
480 IF( cnorm( j ).GT.one )
THEN
485 rec = rec / cnorm( j )
487 CALL dscal( n, rec, x, 1 )
491 x( j ) = x( j ) / tjjs
513 IF( cnorm( j ).GT.( bignum-xmax )*rec )
THEN
518 CALL dscal( n, rec, x, 1 )
521 ELSE IF( xj*cnorm( j ).GT.( bignum-xmax ) )
THEN
525 CALL dscal( n, half, x, 1 )
535 CALL daxpy( j-1, -x( j )*tscal, a( 1, j ), 1, x,
537 i = idamax( j-1, x, 1 )
546 CALL daxpy( n-j, -x( j )*tscal, a( j+1, j ), 1,
548 i = j + idamax( n-j, x( j+1 ), 1 )
558 DO 160 j = jfirst, jlast, jinc
565 rec = one /
max( xmax, one )
566 IF( cnorm( j ).GT.( bignum-xj )*rec )
THEN
572 tjjs = a( j, j )*tscal
577 IF( tjj.GT.one )
THEN
581 rec =
min( one, rec*tjj )
584 IF( rec.LT.one )
THEN
585 CALL dscal( n, rec, x, 1 )
592 IF( uscal.EQ.one )
THEN
598 sumj = ddot( j-1, a( 1, j ), 1, x, 1 )
599 ELSE IF( j.LT.n )
THEN
600 sumj = ddot( n-j, a( j+1, j ), 1, x( j+1 ), 1 )
608 sumj = sumj + ( a( i, j )*uscal )*x( i )
610 ELSE IF( j.LT.n )
THEN
612 sumj = sumj + ( a( i, j )*uscal )*x( i )
617 IF( uscal.EQ.tscal )
THEN
622 x( j ) = x( j ) - sumj
625 tjjs = a( j, j )*tscal
635 IF( tjj.GT.smlnum )
THEN
639 IF( tjj.LT.one )
THEN
640 IF( xj.GT.tjj*bignum )
THEN
645 CALL dscal( n, rec, x, 1 )
650 x( j ) = x( j ) / tjjs
651 ELSE IF( tjj.GT.zero )
THEN
655 IF( xj.GT.tjj*bignum )
THEN
659 rec = ( tjj*bignum ) / xj
660 CALL dscal( n, rec, x, 1 )
664 x( j ) = x( j ) / tjjs
683 x( j ) = x( j ) / tjjs - sumj
685 xmax =
max( xmax, abs( x( j ) ) )
688 scale = scale / tscal
693 IF( tscal.NE.one )
THEN
694 CALL dscal( n, one / tscal, cnorm, 1 )