231 SUBROUTINE slatrs3( UPLO, TRANS, DIAG, NORMIN, N, NRHS, A, LDA,
232 $ X, LDX, SCALE, CNORM, WORK, LWORK, INFO )
236 CHARACTER DIAG, TRANS, NORMIN, UPLO
237 INTEGER INFO, LDA, LWORK, LDX, N, NRHS
240 REAL A( LDA, * ), CNORM( * ), X( LDX, * ),
241 $ scale( * ), work( * )
248 parameter( zero = 0.0e+0, one = 1.0e+0 )
249 INTEGER NBMAX, NBMIN, NBRHS, NRHSMIN
250 parameter( nrhsmin = 2, nbrhs = 32 )
251 parameter( nbmin = 8, nbmax = 64 )
254 REAL 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, lwmin
261 REAL ANRM, BIGNUM, BNRM, RSCAL, SCAL, SCALOC,
262 $ scamin, smlnum, tmax
267 REAL SLAMCH, SLANGE, SLARMM
268 EXTERNAL ilaenv, lsame, slamch, slange,
276 INTRINSIC abs, max, min
281 upper = lsame( uplo,
'U' )
282 notran = lsame( trans,
'N' )
283 nounit = lsame( diag,
'N' )
284 lquery = ( lwork.EQ.-1 )
288 nb = max( 8, ilaenv( 1,
'SLATRS',
'', n, n, -1, -1 ) )
289 nb = min( nbmax, nb )
290 nba = max( 1, (n + nb - 1) / nb )
291 nbx = max( 1, (nrhs + nbrhs - 1) / nbrhs )
302 lscale = nba * max( nba, min( nrhs, nbrhs ) )
313 IF( min( n, nrhs ).EQ.0 )
THEN
316 lwmin = lscale + lanrm
318 work( 1 ) = sroundup_lwork( lwmin )
322 IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
324 ELSE IF( .NOT.notran .AND. .NOT.lsame( trans,
'T' ) .AND. .NOT.
325 $ lsame( trans,
'C' ) )
THEN
327 ELSE IF( .NOT.nounit .AND. .NOT.lsame( diag,
'U' ) )
THEN
329 ELSE IF( .NOT.lsame( normin,
'Y' ) .AND. .NOT.
330 $ lsame( normin,
'N' ) )
THEN
332 ELSE IF( n.LT.0 )
THEN
334 ELSE IF( nrhs.LT.0 )
THEN
336 ELSE IF( lda.LT.max( 1, n ) )
THEN
338 ELSE IF( ldx.LT.max( 1, n ) )
THEN
340 ELSE IF( .NOT.lquery .AND. lwork.LT.lwmin )
THEN
344 CALL xerbla(
'SLATRS3', -info )
346 ELSE IF( lquery )
THEN
358 IF( min( n, nrhs ).EQ.0 )
363 bignum = slamch(
'Overflow' )
364 smlnum = slamch(
'Safe Minimum' )
368 IF( nrhs.LT.nrhsmin )
THEN
369 CALL slatrs( uplo, trans, diag, normin, n, a, lda, x( 1, 1),
370 $ scale( 1 ), cnorm, info )
372 CALL slatrs( uplo, trans, diag,
'Y', n, a, lda, x( 1,
374 $ scale( k ), cnorm, info )
385 j2 = min( j*nb, n ) + 1
395 i2 = min( i*nb, n ) + 1
400 anrm = slange(
'I', i2-i1, j2-j1, a( i1, j1 ), lda,
402 work( awrk + i+(j-1)*nba ) = anrm
404 anrm = slange(
'1', i2-i1, j2-j1, a( i1, j1 ), lda,
406 work( awrk + j+(i-1)*nba ) = anrm
408 tmax = max( tmax, anrm )
412 IF( .NOT. tmax.LE.slamch(
'Overflow') )
THEN
422 CALL slatrs( uplo, trans, diag,
'N', n, a, lda, x( 1,
424 $ scale( k ), cnorm, info )
440 k2 = min( k*nbrhs, nrhs ) + 1
446 work( i+kk*lds ) = one
478 DO j = jfirst, jlast, jinc
483 j2 = min( j*nb, n ) + 1
492 CALL slatrs( uplo, trans, diag,
'N', j2-j1,
493 $ a( j1, j1 ), lda, x( j1, rhs ),
494 $ scaloc, cnorm, info )
496 CALL slatrs( uplo, trans, diag,
'Y', j2-j1,
497 $ a( j1, j1 ), lda, x( j1, rhs ),
498 $ scaloc, cnorm, info )
503 xnrm( kk ) = slange(
'I', j2-j1, 1, x( j1, rhs ),
506 IF( scaloc .EQ. zero )
THEN
520 work( ii+kk*lds ) = one
523 ELSE IF( scaloc*work( j+kk*lds ) .EQ. zero )
THEN
530 scal = work( j+kk*lds ) / smlnum
531 scaloc = scaloc * scal
532 work( j+kk*lds ) = smlnum
537 IF( xnrm( kk )*rscal .LE. bignum )
THEN
538 xnrm( kk ) = xnrm( kk ) * rscal
539 CALL sscal( j2-j1, rscal, x( j1, rhs ), 1 )
553 work( ii+kk*lds ) = one
558 scaloc = scaloc * work( j+kk*lds )
559 work( j+kk*lds ) = scaloc
586 DO i = ifirst, ilast, iinc
591 i2 = min( i*nb, n ) + 1
602 scamin = min( work( i+kk*lds), work( j+kk*lds ) )
607 bnrm = slange(
'I', i2-i1, 1, x( i1, rhs ), ldx,
609 bnrm = bnrm*( scamin / work( i+kk*lds ) )
610 xnrm( kk ) = xnrm( kk )*(scamin / work( j+kk*lds ))
611 anrm = work( awrk + i+(j-1)*nba )
612 scaloc = slarmm( anrm, xnrm( kk ), bnrm )
617 scal = ( scamin / work( i+kk*lds) )*scaloc
618 IF( scal.NE.one )
THEN
619 CALL sscal( i2-i1, scal, x( i1, rhs ), 1 )
620 work( i+kk*lds ) = scamin*scaloc
623 scal = ( scamin / work( j+kk*lds ) )*scaloc
624 IF( scal.NE.one )
THEN
625 CALL sscal( j2-j1, scal, x( j1, rhs ), 1 )
626 work( j+kk*lds ) = scamin*scaloc
634 CALL sgemm(
'N',
'N', i2-i1, k2-k1, j2-j1, -one,
635 $ a( i1, j1 ), lda, x( j1, k1 ), ldx,
636 $ one, x( i1, k1 ), ldx )
641 CALL sgemm(
'T',
'N', i2-i1, k2-k1, j2-j1, -one,
642 $ a( j1, i1 ), lda, x( j1, k1 ), ldx,
643 $ one, x( i1, k1 ), ldx )
653 scale( rhs ) = min( scale( rhs ), work( i+kk*lds ) )
661 IF( scale( rhs ).NE.one .AND. scale( rhs ).NE. zero )
THEN
664 i2 = min( i*nb, n ) + 1
665 scal = scale( rhs ) / work( i+kk*lds )
667 $
CALL sscal( i2-i1, scal, x( i1, rhs ), 1 )
674 work( 1 ) = sroundup_lwork( lwmin )