@@ -140,13 +140,16 @@ SUBROUTINE DLANV2( A, B, C, D, RT1R, RT1I, RT2R, RT2I, CS, SN )
140140*
141141* .. Parameters ..
142142 DOUBLE PRECISION ZERO, HALF, ONE
143- PARAMETER ( ZERO = 0.0D+0 , HALF = 0.5D+0 , ONE = 1.0D+0 )
143+ PARAMETER ( ZERO = 0.0D+0 , HALF = 0.5D+0 , ONE = 1.0D+0 ,
144+ $ TWO = 2.0D0 )
144145 DOUBLE PRECISION MULTPL
145146 PARAMETER ( MULTPL = 4.0D+0 )
146147* ..
147148* .. Local Scalars ..
148149 DOUBLE PRECISION AA, BB, BCMAX, BCMIS, CC, CS1, DD, EPS, P, SAB,
149- $ SAC, SCALE, SIGMA, SN1, TAU, TEMP, Z
150+ $ SAC, SCALE, SIGMA, SN1, TAU, TEMP, Z, SAFMIN,
151+ $ SAFMN2, SAFMX2
152+ INTEGER COUNT
150153* ..
151154* .. External Functions ..
152155 DOUBLE PRECISION DLAMCH, DLAPY2
@@ -157,7 +160,11 @@ SUBROUTINE DLANV2( A, B, C, D, RT1R, RT1I, RT2R, RT2I, CS, SN )
157160* ..
158161* .. Executable Statements ..
159162*
163+ SAFMIN = DLAMCH( ' S' )
160164 EPS = DLAMCH( ' P' )
165+ SAFMN2 = DLAMCH( ' B' )** INT ( LOG ( SAFMIN / EPS ) /
166+ $ LOG ( DLAMCH( ' B' ) ) / TWO )
167+ SAFMX2 = ONE / SAFMN2
161168 IF ( C.EQ. ZERO ) THEN
162169 CS = ONE
163170 SN = ZERO
@@ -212,7 +219,24 @@ SUBROUTINE DLANV2( A, B, C, D, RT1R, RT1I, RT2R, RT2I, CS, SN )
212219* Complex eigenvalues, or real (almost) equal eigenvalues.
213220* Make diagonal elements equal.
214221*
222+ COUNT = 0
215223 SIGMA = B + C
224+ 10 CONTINUE
225+ COUNT = COUNT + 1
226+ SCALE = MAX ( ABS (TEMP), ABS (SIGMA) )
227+ IF ( SCALE.GE. SAFMX2 ) THEN
228+ SIGMA = SIGMA * SAFMN2
229+ TEMP = TEMP * SAFMN2
230+ IF (COUNT .LE. 20 )
231+ $ GOTO 10
232+ END IF
233+ IF ( SCALE.LE. SAFMN2 ) THEN
234+ SIGMA = SIGMA * SAFMX2
235+ TEMP = TEMP * SAFMX2
236+ IF (COUNT .LE. 20 )
237+ $ GOTO 10
238+ END IF
239+ P = HALF* TEMP
216240 TAU = DLAPY2( SIGMA, TEMP )
217241 CS = SQRT ( HALF* ( ONE+ ABS ( SIGMA ) / TAU ) )
218242 SN = - ( P / ( TAU* CS ) )* SIGN ( ONE, SIGMA )
0 commit comments