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)
XERBLA
subroutine dgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
DGEMM
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
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...