227 SUBROUTINE slatrs3( 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 REAL A( LDA, * ), CNORM( * ), X( LDX, * ),
237 $ scale( * ), work( * )
244 parameter( zero = 0.0e+0, one = 1.0e+0 )
245 INTEGER NBMAX, NBMIN, NBRHS, NRHSMIN
246 parameter( nrhsmin = 2, nbrhs = 32 )
247 parameter( nbmin = 8, nbmax = 64 )
250 REAL 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 REAL ANRM, BIGNUM, BNRM, RSCAL, SCAL, SCALOC,
258 $ scamin, smlnum, tmax
263 REAL SLAMCH, SLANGE, SLARMM
264 EXTERNAL ilaenv, lsame, slamch, slange, slarmm
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,
'SLATRS',
'', 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(
'SLATRS3', -info )
331 ELSE IF( lquery )
THEN
343 IF( min( n, nrhs ).EQ.0 )
348 bignum = slamch(
'Overflow' )
349 smlnum = slamch(
'Safe Minimum' )
353 IF( nrhs.LT.nrhsmin )
THEN
354 CALL slatrs( uplo, trans, diag, normin, n, a, lda, x( 1, 1),
355 $ scale( 1 ), cnorm, info )
357 CALL slatrs( 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 = slange(
'I', i2-i1, j2-j1, a( i1, j1 ), lda, w )
385 work( awrk + i+(j-1)*nba ) = anrm
387 anrm = slange(
'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.slamch(
'Overflow') )
THEN
404 CALL slatrs( 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 slatrs( uplo, trans, diag,
'N', j2-j1,
474 $ a( j1, j1 ), lda, x( j1, rhs ),
475 $ scaloc, cnorm, info )
477 CALL slatrs( uplo, trans, diag,
'Y', j2-j1,
478 $ a( j1, j1 ), lda, x( j1, rhs ),
479 $ scaloc, cnorm, info )
484 xnrm( kk ) = slange(
'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 sscal( 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 = slange(
'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 = slarmm( anrm, xnrm( kk ), bnrm )
597 scal = ( scamin / work( i+kk*lds) )*scaloc
598 IF( scal.NE.one )
THEN
599 CALL sscal( 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 sscal( j2-j1, scal, x( j1, rhs ), 1 )
606 work( j+kk*lds ) = scamin*scaloc
614 CALL sgemm(
'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 sgemm(
'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 sscal( i2-i1, scal, x( i1, rhs ), 1 )
subroutine xerbla(srname, info)
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
subroutine slatrs3(uplo, trans, diag, normin, n, nrhs, a, lda, x, ldx, scale, cnorm, work, lwork, info)
SLATRS3 solves a triangular system of equations with the scale factors set to prevent overflow.
subroutine slatrs(uplo, trans, diag, normin, n, a, lda, x, scale, cnorm, info)
SLATRS solves a triangular system of equations with the scale factor set to prevent overflow.
subroutine sscal(n, sa, sx, incx)
SSCAL