227 SUBROUTINE dlatrs3( UPLO, TRANS, DIAG, NORMIN, N, NRHS, A, LDA,
228 $ X, LDX, SCALE, CNORM, WORK, LWORK, INFO )
232 CHARACTER DIAG, TRANS, NORMIN, UPLO
233 INTEGER INFO, LDA, LWORK, LDX, N, NRHS
236 DOUBLE PRECISION A( LDA, * ), CNORM( * ), X( LDX, * ),
237 $ scale( * ), work( * )
243 DOUBLE PRECISION ZERO, ONE
244 parameter( zero = 0.0d+0, one = 1.0d+0 )
245 INTEGER NBMAX, NBMIN, NBRHS, NRHSMIN
246 parameter( nrhsmin = 2, nbrhs = 32 )
247 parameter( nbmin = 8, nbmax = 64 )
250 DOUBLE PRECISION W( NBMAX ), XNRM( NBRHS )
253 LOGICAL LQUERY, NOTRAN, NOUNIT, UPPER
254 INTEGER AWRK, I, IFIRST, IINC, ILAST, II, I1, I2, J,
255 $ jfirst, jinc, jlast, j1, j2, k, kk, k1, k2,
256 $ lanrm, lds, lscale, nb, nba, nbx, rhs
257 DOUBLE PRECISION ANRM, BIGNUM, BNRM, RSCAL, SCAL, SCALOC,
258 $ scamin, smlnum, tmax
263 DOUBLE PRECISION DLAMCH, DLANGE, DLARMM
264 EXTERNAL dlamch, dlange, dlarmm, ilaenv, lsame
270 INTRINSIC abs, max, min
275 upper = lsame( uplo,
'U' )
276 notran = lsame( trans,
'N' )
277 nounit = lsame( diag,
'N' )
278 lquery = ( lwork.EQ.-1 )
282 nb = max( 8, ilaenv( 1,
'DLATRS',
'', n, n, -1, -1 ) )
283 nb = min( nbmax, nb )
284 nba = max( 1, (n + nb - 1) / nb )
285 nbx = max( 1, (nrhs + nbrhs - 1) / nbrhs )
295 lscale = nba * max( nba, min( nrhs, nbrhs ) )
303 work( 1 ) = lscale + lanrm
307 IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
309 ELSE IF( .NOT.notran .AND. .NOT.lsame( trans,
'T' ) .AND. .NOT.
310 $ lsame( trans,
'C' ) )
THEN
312 ELSE IF( .NOT.nounit .AND. .NOT.lsame( diag,
'U' ) )
THEN
314 ELSE IF( .NOT.lsame( normin,
'Y' ) .AND. .NOT.
315 $ lsame( normin,
'N' ) )
THEN
317 ELSE IF( n.LT.0 )
THEN
319 ELSE IF( nrhs.LT.0 )
THEN
321 ELSE IF( lda.LT.max( 1, n ) )
THEN
323 ELSE IF( ldx.LT.max( 1, n ) )
THEN
325 ELSE IF( .NOT.lquery .AND. lwork.LT.work( 1 ) )
THEN
329 CALL xerbla(
'DLATRS3', -info )
331 ELSE IF( lquery )
THEN
343 IF( min( n, nrhs ).EQ.0 )
348 bignum = dlamch(
'Overflow' )
349 smlnum = dlamch(
'Safe Minimum' )
353 IF( nrhs.LT.nrhsmin )
THEN
354 CALL dlatrs( uplo, trans, diag, normin, n, a, lda, x( 1, 1),
355 $ scale( 1 ), cnorm, info )
357 CALL dlatrs( uplo, trans, diag,
'Y', n, a, lda, x( 1, k ),
358 $ scale( k ), cnorm, info )
369 j2 = min( j*nb, n ) + 1
379 i2 = min( i*nb, n ) + 1
384 anrm = dlange(
'I', i2-i1, j2-j1, a( i1, j1 ), lda, w )
385 work( awrk + i+(j-1)*nba ) = anrm
387 anrm = dlange(
'1', i2-i1, j2-j1, a( i1, j1 ), lda, w )
388 work( awrk + j+(i-1)*nba ) = anrm
390 tmax = max( tmax, anrm )
394 IF( .NOT. tmax.LE.dlamch(
'Overflow') )
THEN
404 CALL dlatrs( uplo, trans, diag,
'N', n, a, lda, x( 1, k ),
405 $ scale( k ), cnorm, info )
421 k2 = min( k*nbrhs, nrhs ) + 1
427 work( i+kk*lds ) = one
459 DO j = jfirst, jlast, jinc
464 j2 = min( j*nb, n ) + 1
473 CALL dlatrs( uplo, trans, diag,
'N', j2-j1,
474 $ a( j1, j1 ), lda, x( j1, rhs ),
475 $ scaloc, cnorm, info )
477 CALL dlatrs( uplo, trans, diag,
'Y', j2-j1,
478 $ a( j1, j1 ), lda, x( j1, rhs ),
479 $ scaloc, cnorm, info )
484 xnrm( kk ) = dlange(
'I', j2-j1, 1, x( j1, rhs ),
487 IF( scaloc .EQ. zero )
THEN
501 work( ii+kk*lds ) = one
504 ELSE IF( scaloc * work( j+kk*lds ) .EQ. zero )
THEN
511 scal = work( j+kk*lds ) / smlnum
512 scaloc = scaloc * scal
513 work( j+kk*lds ) = smlnum
518 IF( xnrm( kk ) * rscal .LE. bignum )
THEN
519 xnrm( kk ) = xnrm( kk ) * rscal
520 CALL dscal( j2-j1, rscal, x( j1, rhs ), 1 )
534 work( ii+kk*lds ) = one
539 scaloc = scaloc * work( j+kk*lds )
540 work( j+kk*lds ) = scaloc
567 DO i = ifirst, ilast, iinc
572 i2 = min( i*nb, n ) + 1
583 scamin = min( work( i + kk*lds), work( j + kk*lds ) )
588 bnrm = dlange(
'I', i2-i1, 1, x( i1, rhs ), ldx, w )
589 bnrm = bnrm*( scamin / work( i+kk*lds ) )
590 xnrm( kk ) = xnrm( kk )*(scamin / work( j+kk*lds ))
591 anrm = work( awrk + i+(j-1)*nba )
592 scaloc = dlarmm( anrm, xnrm( kk ), bnrm )
597 scal = ( scamin / work( i+kk*lds) )*scaloc
598 IF( scal.NE.one )
THEN
599 CALL dscal( i2-i1, scal, x( i1, rhs ), 1 )
600 work( i+kk*lds ) = scamin*scaloc
603 scal = ( scamin / work( j+kk*lds ) )*scaloc
604 IF( scal.NE.one )
THEN
605 CALL dscal( j2-j1, scal, x( j1, rhs ), 1 )
606 work( j+kk*lds ) = scamin*scaloc
614 CALL dgemm(
'N',
'N', i2-i1, k2-k1, j2-j1, -one,
615 $ a( i1, j1 ), lda, x( j1, k1 ), ldx,
616 $ one, x( i1, k1 ), ldx )
621 CALL dgemm(
'T',
'N', i2-i1, k2-k1, j2-j1, -one,
622 $ a( j1, i1 ), lda, x( j1, k1 ), ldx,
623 $ one, x( i1, k1 ), ldx )
633 scale( rhs ) = min( scale( rhs ), work( i+kk*lds ) )
641 IF( scale( rhs ).NE.one .AND. scale( rhs ).NE. zero )
THEN
644 i2 = min( i*nb, n ) + 1
645 scal = scale( rhs ) / work( i+kk*lds )
647 $
CALL dscal( i2-i1, scal, x( i1, rhs ), 1 )
subroutine xerbla(srname, info)
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dlatrs3(uplo, trans, diag, normin, n, nrhs, a, lda, x, ldx, scale, cnorm, work, lwork, info)
DLATRS3 solves a triangular system of equations with the scale factors set to prevent overflow.
subroutine dlatrs(uplo, trans, diag, normin, n, a, lda, x, scale, cnorm, info)
DLATRS solves a triangular system of equations with the scale factor set to prevent overflow.
subroutine dscal(n, da, dx, incx)
DSCAL