233 SUBROUTINE clatrs3( UPLO, TRANS, DIAG, NORMIN, N, NRHS, A, LDA,
234 $ X, LDX, SCALE, CNORM, WORK, LWORK, INFO )
238 CHARACTER DIAG, TRANS, NORMIN, UPLO
239 INTEGER INFO, LDA, LWORK, LDX, N, NRHS
242 COMPLEX A( LDA, * ), X( LDX, * )
243 REAL CNORM( * ), SCALE( * ), WORK( * )
250 parameter( zero = 0.0e+0, one = 1.0e+0 )
252 parameter( czero = ( 0.0e+0, 0.0e+0 ) )
253 parameter( cone = ( 1.0e+0, 0.0e+0 ) )
254 INTEGER NBMAX, NBMIN, NBRHS, NRHSMIN
255 parameter( nrhsmin = 2, nbrhs = 32 )
256 parameter( nbmin = 8, nbmax = 64 )
259 REAL W( NBMAX ), XNRM( NBRHS )
262 LOGICAL LQUERY, NOTRAN, NOUNIT, UPPER
263 INTEGER AWRK, I, IFIRST, IINC, ILAST, II, I1, I2, J,
264 $ jfirst, jinc, jlast, j1, j2, k, kk, k1, k2,
265 $ lanrm, lds, lscale, nb, nba, nbx, rhs, lwmin
266 REAL ANRM, BIGNUM, BNRM, RSCAL, SCAL, SCALOC,
267 $ scamin, smlnum, tmax
272 REAL SLAMCH, CLANGE, SLARMM,
274 EXTERNAL ilaenv, lsame, slamch,
281 INTRINSIC abs, max, min
286 upper = lsame( uplo,
'U' )
287 notran = lsame( trans,
'N' )
288 nounit = lsame( diag,
'N' )
289 lquery = ( lwork.EQ.-1 )
293 nb = max( nbmin, ilaenv( 1,
'CLATRS',
'', n, n, -1, -1 ) )
294 nb = min( nbmax, nb )
295 nba = max( 1, (n + nb - 1) / nb )
296 nbx = max( 1, (nrhs + nbrhs - 1) / nbrhs )
307 lscale = nba * max( nba, min( nrhs, nbrhs ) )
318 IF( min( n, nrhs ).EQ.0 )
THEN
321 lwmin = lscale + lanrm
327 IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
329 ELSE IF( .NOT.notran .AND. .NOT.lsame( trans,
'T' ) .AND. .NOT.
330 $ lsame( trans,
'C' ) )
THEN
332 ELSE IF( .NOT.nounit .AND. .NOT.lsame( diag,
'U' ) )
THEN
334 ELSE IF( .NOT.lsame( normin,
'Y' ) .AND. .NOT.
335 $ lsame( normin,
'N' ) )
THEN
337 ELSE IF( n.LT.0 )
THEN
339 ELSE IF( nrhs.LT.0 )
THEN
341 ELSE IF( lda.LT.max( 1, n ) )
THEN
343 ELSE IF( ldx.LT.max( 1, n ) )
THEN
345 ELSE IF( .NOT.lquery .AND. lwork.LT.lwmin )
THEN
349 CALL xerbla(
'CLATRS3', -info )
351 ELSE IF( lquery )
THEN
363 IF( min( n, nrhs ).EQ.0 )
368 bignum = slamch(
'Overflow' )
369 smlnum = slamch(
'Safe Minimum' )
373 IF( nrhs.LT.nrhsmin )
THEN
374 CALL clatrs( uplo, trans, diag, normin, n, a, lda, x( 1,
376 $ scale( 1 ), cnorm, info )
378 CALL clatrs( uplo, trans, diag,
'Y', n, a, lda, x( 1,
380 $ scale( k ), cnorm, info )
391 j2 = min( j*nb, n ) + 1
401 i2 = min( i*nb, n ) + 1
406 anrm = clange(
'I', i2-i1, j2-j1, a( i1, j1 ), lda,
408 work( awrk + i+(j-1)*nba ) = anrm
410 anrm = clange(
'1', i2-i1, j2-j1, a( i1, j1 ), lda,
412 work( awrk + j+(i-1)*nba ) = anrm
414 tmax = max( tmax, anrm )
418 IF( .NOT. tmax.LE.slamch(
'Overflow') )
THEN
428 CALL clatrs( uplo, trans, diag,
'N', n, a, lda, x( 1,
430 $ scale( k ), cnorm, info )
446 k2 = min( k*nbrhs, nrhs ) + 1
452 work( i+kk*lds ) = one
485 DO j = jfirst, jlast, jinc
490 j2 = min( j*nb, n ) + 1
497 CALL clatrs( uplo, trans, diag,
'N', j2-j1,
498 $ a( j1, j1 ), lda, x( j1, rhs ),
499 $ scaloc, cnorm, info )
501 CALL clatrs( uplo, trans, diag,
'Y', j2-j1,
502 $ a( j1, j1 ), lda, x( j1, rhs ),
503 $ scaloc, cnorm, info )
508 xnrm( kk ) = clange(
'I', j2-j1, 1, x( j1, rhs ),
511 IF( scaloc .EQ. zero )
THEN
525 work( ii+kk*lds ) = one
528 ELSE IF( scaloc*work( j+kk*lds ) .EQ. zero )
THEN
535 scal = work( j+kk*lds ) / smlnum
536 scaloc = scaloc * scal
537 work( j+kk*lds ) = smlnum
542 IF( xnrm( kk )*rscal .LE. bignum )
THEN
543 xnrm( kk ) = xnrm( kk ) * rscal
544 CALL csscal( j2-j1, rscal, x( j1, rhs ), 1 )
558 work( ii+kk*lds ) = one
563 scaloc = scaloc * work( j+kk*lds )
564 work( j+kk*lds ) = scaloc
591 DO i = ifirst, ilast, iinc
596 i2 = min( i*nb, n ) + 1
607 scamin = min( work( i+kk*lds), work( j+kk*lds ) )
612 bnrm = clange(
'I', i2-i1, 1, x( i1, rhs ), ldx,
614 bnrm = bnrm*( scamin / work( i+kk*lds ) )
615 xnrm( kk ) = xnrm( kk )*( scamin / work( j+kk*lds) )
616 anrm = work( awrk + i+(j-1)*nba )
617 scaloc = slarmm( anrm, xnrm( kk ), bnrm )
622 scal = ( scamin / work( i+kk*lds) )*scaloc
623 IF( scal.NE.one )
THEN
624 CALL csscal( i2-i1, scal, x( i1, rhs ), 1 )
625 work( i+kk*lds ) = scamin*scaloc
628 scal = ( scamin / work( j+kk*lds ) )*scaloc
629 IF( scal.NE.one )
THEN
630 CALL csscal( j2-j1, scal, x( j1, rhs ), 1 )
631 work( j+kk*lds ) = scamin*scaloc
639 CALL cgemm(
'N',
'N', i2-i1, k2-k1, j2-j1, -cone,
640 $ a( i1, j1 ), lda, x( j1, k1 ), ldx,
641 $ cone, x( i1, k1 ), ldx )
642 ELSE IF( lsame( trans,
'T' ) )
THEN
646 CALL cgemm(
'T',
'N', i2-i1, k2-k1, j2-j1, -cone,
647 $ a( j1, i1 ), lda, x( j1, k1 ), ldx,
648 $ cone, x( i1, k1 ), ldx )
653 CALL cgemm(
'C',
'N', i2-i1, k2-k1, j2-j1, -cone,
654 $ a( j1, i1 ), lda, x( j1, k1 ), ldx,
655 $ cone, x( i1, k1 ), ldx )
665 scale( rhs ) = min( scale( rhs ), work( i+kk*lds ) )
673 IF( scale( rhs ).NE.one .AND. scale( rhs ).NE. zero )
THEN
676 i2 = min( i*nb, n ) + 1
677 scal = scale( rhs ) / work( i+kk*lds )
679 $
CALL csscal( i2-i1, scal, x( i1, rhs ), 1 )