@@ -274,7 +274,7 @@ SUBROUTINE CLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE,
274274 $ CDOTU, CLADIV
275275* ..
276276* .. External Subroutines ..
277- EXTERNAL CAXPY, CSSCAL, CTRSV, SLABAD, SSCAL, XERBLA
277+ EXTERNAL CAXPY, CSSCAL, CTRSV, SSCAL, XERBLA
278278* ..
279279* .. Intrinsic Functions ..
280280 INTRINSIC ABS, AIMAG, CMPLX, CONJG, MAX, MIN, REAL
@@ -318,17 +318,14 @@ SUBROUTINE CLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE,
318318*
319319* Quick return if possible
320320*
321+ SCALE = ONE
321322 IF ( N.EQ. 0 )
322323 $ RETURN
323324*
324325* Determine machine dependent parameters to control overflow.
325326*
326- SMLNUM = SLAMCH( ' Safe minimum' )
327- BIGNUM = ONE / SMLNUM
328- CALL SLABAD( SMLNUM, BIGNUM )
329- SMLNUM = SMLNUM / SLAMCH( ' Precision' )
327+ SMLNUM = SLAMCH( ' Safe minimum' ) / SLAMCH( ' Precision' )
330328 BIGNUM = ONE / SMLNUM
331- SCALE = ONE
332329*
333330 IF ( LSAME( NORMIN, ' N' ) ) THEN
334331*
@@ -360,8 +357,74 @@ SUBROUTINE CLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE,
360357 IF ( TMAX.LE. BIGNUM* HALF ) THEN
361358 TSCAL = ONE
362359 ELSE
363- TSCAL = HALF / ( SMLNUM* TMAX )
364- CALL SSCAL( N, TSCAL, CNORM, 1 )
360+ *
361+ * Avoid NaN generation if entries in CNORM exceed the
362+ * overflow threshold
363+ *
364+ IF ( TMAX.LE. SLAMCH(' Overflow' ) ) THEN
365+ * Case 1: All entries in CNORM are valid floating-point numbers
366+ TSCAL = HALF / ( SMLNUM* TMAX )
367+ CALL SSCAL( N, TSCAL, CNORM, 1 )
368+ ELSE
369+ * Case 2: At least one column norm of A cannot be
370+ * represented as a floating-point number. Find the
371+ * maximum offdiagonal absolute value
372+ * max( |Re(A(I,J))|, |Im(A(I,J)| ). If this entry is
373+ * not +/- Infinity, use this value as TSCAL.
374+ TMAX = ZERO
375+ IF ( UPPER ) THEN
376+ *
377+ * A is upper triangular.
378+ *
379+ DO J = 2 , N
380+ DO I = 1 , J - 1
381+ TMAX = MAX ( TMAX, ABS ( REAL ( A( I, J ) ) ),
382+ $ ABS ( AIMAG (A ( I, J ) ) ) )
383+ END DO
384+ END DO
385+ ELSE
386+ *
387+ * A is lower triangular.
388+ *
389+ DO J = 1 , N - 1
390+ DO I = J + 1 , N
391+ TMAX = MAX ( TMAX, ABS ( REAL ( A( I, J ) ) ),
392+ $ ABS ( AIMAG (A ( I, J ) ) ) )
393+ END DO
394+ END DO
395+ END IF
396+ *
397+ IF ( TMAX.LE. SLAMCH(' Overflow' ) ) THEN
398+ TSCAL = ONE / ( SMLNUM* TMAX )
399+ DO J = 1 , N
400+ IF ( CNORM( J ).LE. SLAMCH(' Overflow' ) ) THEN
401+ CNORM( J ) = CNORM( J )* TSCAL
402+ ELSE
403+ * Recompute the 1-norm of each column without
404+ * introducing Infinity in the summation.
405+ TSCAL = TWO * TSCAL
406+ CNORM( J ) = ZERO
407+ IF ( UPPER ) THEN
408+ DO I = 1 , J - 1
409+ CNORM( J ) = CNORM( J ) +
410+ $ TSCAL * CABS2( A( I, J ) )
411+ END DO
412+ ELSE
413+ DO I = J + 1 , N
414+ CNORM( J ) = CNORM( J ) +
415+ $ TSCAL * CABS2( A( I, J ) )
416+ END DO
417+ END IF
418+ TSCAL = TSCAL * HALF
419+ END IF
420+ END DO
421+ ELSE
422+ * At least one entry of A is not a valid floating-point
423+ * entry. Rely on TRSV to propagate Inf and NaN.
424+ CALL CTRSV( UPLO, TRANS, DIAG, N, A, LDA, X, 1 )
425+ RETURN
426+ END IF
427+ END IF
365428 END IF
366429*
367430* Compute a bound on the computed solution vector to see if the
0 commit comments