228 SUBROUTINE zlatrs3( UPLO, TRANS, DIAG, NORMIN, N, NRHS, A, LDA,
229 $ X, LDX, SCALE, CNORM, WORK, LWORK, INFO )
233 CHARACTER DIAG, TRANS, NORMIN, UPLO
234 INTEGER INFO, LDA, LWORK, LDX, N, NRHS
237 COMPLEX*16 A( LDA, * ), X( LDX, * )
238 DOUBLE PRECISION CNORM( * ), SCALE( * ), WORK( * )
244 DOUBLE PRECISION ZERO, ONE
245 parameter( zero = 0.0d+0, one = 1.0d+0 )
246 COMPLEX*16 CZERO, CONE
247 parameter( cone = ( 1.0d+0, 0.0d+0 ) )
248 parameter( czero = ( 0.0d+0, 0.0d+0 ) )
249 INTEGER NBMAX, NBMIN, NBRHS, NRHSMIN
250 parameter( nrhsmin = 2, nbrhs = 32 )
251 parameter( nbmin = 8, nbmax = 64 )
254 DOUBLE PRECISION W( NBMAX ), XNRM( NBRHS )
257 LOGICAL LQUERY, NOTRAN, NOUNIT, UPPER
258 INTEGER AWRK, I, IFIRST, IINC, ILAST, II, I1, I2, J,
259 $ jfirst, jinc, jlast, j1, j2, k, kk, k1, k2,
260 $ lanrm, lds, lscale, nb, nba, nbx, rhs
261 DOUBLE PRECISION ANRM, BIGNUM, BNRM, RSCAL, SCAL, SCALOC,
262 $ scamin, smlnum, tmax
267 DOUBLE PRECISION DLAMCH, ZLANGE, DLARMM
268 EXTERNAL ilaenv, lsame, dlamch, zlange, dlarmm
274 INTRINSIC abs, max, min
279 upper = lsame( uplo,
'U' )
280 notran = lsame( trans,
'N' )
281 nounit = lsame( diag,
'N' )
282 lquery = ( lwork.EQ.-1 )
286 nb = max( nbmin, ilaenv( 1,
'ZLATRS',
'', n, n, -1, -1 ) )
287 nb = min( nbmax, nb )
288 nba = max( 1, (n + nb - 1) / nb )
289 nbx = max( 1, (nrhs + nbrhs - 1) / nbrhs )
299 lscale = nba * max( nba, min( nrhs, nbrhs ) )
307 work( 1 ) = lscale + lanrm
311 IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
313 ELSE IF( .NOT.notran .AND. .NOT.lsame( trans,
'T' ) .AND. .NOT.
314 $ lsame( trans,
'C' ) )
THEN
316 ELSE IF( .NOT.nounit .AND. .NOT.lsame( diag,
'U' ) )
THEN
318 ELSE IF( .NOT.lsame( normin,
'Y' ) .AND. .NOT.
319 $ lsame( normin,
'N' ) )
THEN
321 ELSE IF( n.LT.0 )
THEN
323 ELSE IF( nrhs.LT.0 )
THEN
325 ELSE IF( lda.LT.max( 1, n ) )
THEN
327 ELSE IF( ldx.LT.max( 1, n ) )
THEN
329 ELSE IF( .NOT.lquery .AND. lwork.LT.work( 1 ) )
THEN
333 CALL xerbla(
'ZLATRS3', -info )
335 ELSE IF( lquery )
THEN
347 IF( min( n, nrhs ).EQ.0 )
352 bignum = dlamch(
'Overflow' )
353 smlnum = dlamch(
'Safe Minimum' )
357 IF( nrhs.LT.nrhsmin )
THEN
358 CALL zlatrs( uplo, trans, diag, normin, n, a, lda, x( 1, 1),
359 $ scale( 1 ), cnorm, info )
361 CALL zlatrs( uplo, trans, diag,
'Y', n, a, lda, x( 1, k ),
362 $ scale( k ), cnorm, info )
373 j2 = min( j*nb, n ) + 1
383 i2 = min( i*nb, n ) + 1
388 anrm = zlange(
'I', i2-i1, j2-j1, a( i1, j1 ), lda, w )
389 work( awrk + i+(j-1)*nba ) = anrm
391 anrm = zlange(
'1', i2-i1, j2-j1, a( i1, j1 ), lda, w )
392 work( awrk + j+(i-1) * nba ) = anrm
394 tmax = max( tmax, anrm )
398 IF( .NOT. tmax.LE.dlamch(
'Overflow') )
THEN
408 CALL zlatrs( uplo, trans, diag,
'N', n, a, lda, x( 1, k ),
409 $ scale( k ), cnorm, info )
425 k2 = min( k*nbrhs, nrhs ) + 1
431 work( i+kk*lds ) = one
464 DO j = jfirst, jlast, jinc
469 j2 = min( j*nb, n ) + 1
476 CALL zlatrs( uplo, trans, diag,
'N', j2-j1,
477 $ a( j1, j1 ), lda, x( j1, rhs ),
478 $ scaloc, cnorm, info )
480 CALL zlatrs( uplo, trans, diag,
'Y', j2-j1,
481 $ a( j1, j1 ), lda, x( j1, rhs ),
482 $ scaloc, cnorm, info )
487 xnrm( kk ) = zlange(
'I', j2-j1, 1, x( j1, rhs ),
490 IF( scaloc .EQ. zero )
THEN
504 work( ii+kk*lds ) = one
507 ELSE IF( scaloc*work( j+kk*lds ) .EQ. zero )
THEN
514 scal = work( j+kk*lds ) / smlnum
515 scaloc = scaloc * scal
516 work( j+kk*lds ) = smlnum
521 IF( xnrm( kk )*rscal .LE. bignum )
THEN
522 xnrm( kk ) = xnrm( kk ) * rscal
523 CALL zdscal( j2-j1, rscal, x( j1, rhs ), 1 )
537 work( ii+kk*lds ) = one
542 scaloc = scaloc * work( j+kk*lds )
543 work( j+kk*lds ) = scaloc
570 DO i = ifirst, ilast, iinc
575 i2 = min( i*nb, n ) + 1
586 scamin = min( work( i+kk*lds), work( j+kk*lds ) )
591 bnrm = zlange(
'I', i2-i1, 1, x( i1, rhs ), ldx, w )
592 bnrm = bnrm*( scamin / work( i+kk*lds ) )
593 xnrm( kk ) = xnrm( kk )*( scamin / work( j+kk*lds) )
594 anrm = work( awrk + i+(j-1)*nba )
595 scaloc = dlarmm( anrm, xnrm( kk ), bnrm )
600 scal = ( scamin / work( i+kk*lds) )*scaloc
601 IF( scal.NE.one )
THEN
602 CALL zdscal( i2-i1, scal, x( i1, rhs ), 1 )
603 work( i+kk*lds ) = scamin*scaloc
606 scal = ( scamin / work( j+kk*lds ) )*scaloc
607 IF( scal.NE.one )
THEN
608 CALL zdscal( j2-j1, scal, x( j1, rhs ), 1 )
609 work( j+kk*lds ) = scamin*scaloc
617 CALL zgemm(
'N',
'N', i2-i1, k2-k1, j2-j1, -cone,
618 $ a( i1, j1 ), lda, x( j1, k1 ), ldx,
619 $ cone, x( i1, k1 ), ldx )
620 ELSE IF( lsame( trans,
'T' ) )
THEN
624 CALL zgemm(
'T',
'N', i2-i1, k2-k1, j2-j1, -cone,
625 $ a( j1, i1 ), lda, x( j1, k1 ), ldx,
626 $ cone, x( i1, k1 ), ldx )
631 CALL zgemm(
'C',
'N', i2-i1, k2-k1, j2-j1, -cone,
632 $ a( j1, i1 ), lda, x( j1, k1 ), ldx,
633 $ cone, x( i1, k1 ), ldx )
644 scale( rhs ) = min( scale( rhs ), work( i+kk*lds ) )
652 IF( scale( rhs ).NE.one .AND. scale( rhs ).NE. zero )
THEN
654 i1 = (i - 1) * nb + 1
655 i2 = min( i * nb, n ) + 1
656 scal = scale( rhs ) / work( i+kk*lds )
658 $
CALL zdscal( i2-i1, scal, x( i1, rhs ), 1 )
subroutine xerbla(srname, info)
subroutine zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
ZGEMM
subroutine zlatrs3(uplo, trans, diag, normin, n, nrhs, a, lda, x, ldx, scale, cnorm, work, lwork, info)
ZLATRS3 solves a triangular system of equations with the scale factors set to prevent overflow.
subroutine zlatrs(uplo, trans, diag, normin, n, a, lda, x, scale, cnorm, info)
ZLATRS solves a triangular system of equations with the scale factor set to prevent overflow.
subroutine zdscal(n, da, zx, incx)
ZDSCAL