00001 SUBROUTINE SLAED6( KNITER, ORGATI, RHO, D, Z, FINIT, TAU, INFO )
00002
00003
00004
00005
00006
00007
00008
00009 LOGICAL ORGATI
00010 INTEGER INFO, KNITER
00011 REAL FINIT, RHO, TAU
00012
00013
00014 REAL D( 3 ), Z( 3 )
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 INTEGER MAXIT
00084 PARAMETER ( MAXIT = 40 )
00085 REAL ZERO, ONE, TWO, THREE, FOUR, EIGHT
00086 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0,
00087 $ THREE = 3.0E0, FOUR = 4.0E0, EIGHT = 8.0E0 )
00088
00089
00090 REAL SLAMCH
00091 EXTERNAL SLAMCH
00092
00093
00094 REAL DSCALE( 3 ), ZSCALE( 3 )
00095
00096
00097 LOGICAL SCALE
00098 INTEGER I, ITER, NITER
00099 REAL A, B, BASE, C, DDF, DF, EPS, ERRETM, ETA, F,
00100 $ FC, SCLFAC, SCLINV, SMALL1, SMALL2, SMINV1,
00101 $ SMINV2, TEMP, TEMP1, TEMP2, TEMP3, TEMP4,
00102 $ LBD, UBD
00103
00104
00105 INTRINSIC ABS, INT, LOG, MAX, MIN, SQRT
00106
00107
00108
00109 INFO = 0
00110
00111 IF( ORGATI ) THEN
00112 LBD = D(2)
00113 UBD = D(3)
00114 ELSE
00115 LBD = D(1)
00116 UBD = D(2)
00117 END IF
00118 IF( FINIT .LT. ZERO )THEN
00119 LBD = ZERO
00120 ELSE
00121 UBD = ZERO
00122 END IF
00123
00124 NITER = 1
00125 TAU = ZERO
00126 IF( KNITER.EQ.2 ) THEN
00127 IF( ORGATI ) THEN
00128 TEMP = ( D( 3 )-D( 2 ) ) / TWO
00129 C = RHO + Z( 1 ) / ( ( D( 1 )-D( 2 ) )-TEMP )
00130 A = C*( D( 2 )+D( 3 ) ) + Z( 2 ) + Z( 3 )
00131 B = C*D( 2 )*D( 3 ) + Z( 2 )*D( 3 ) + Z( 3 )*D( 2 )
00132 ELSE
00133 TEMP = ( D( 1 )-D( 2 ) ) / TWO
00134 C = RHO + Z( 3 ) / ( ( D( 3 )-D( 2 ) )-TEMP )
00135 A = C*( D( 1 )+D( 2 ) ) + Z( 1 ) + Z( 2 )
00136 B = C*D( 1 )*D( 2 ) + Z( 1 )*D( 2 ) + Z( 2 )*D( 1 )
00137 END IF
00138 TEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )
00139 A = A / TEMP
00140 B = B / TEMP
00141 C = C / TEMP
00142 IF( C.EQ.ZERO ) THEN
00143 TAU = B / A
00144 ELSE IF( A.LE.ZERO ) THEN
00145 TAU = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
00146 ELSE
00147 TAU = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
00148 END IF
00149 IF( TAU .LT. LBD .OR. TAU .GT. UBD )
00150 $ TAU = ( LBD+UBD )/TWO
00151 IF( D(1).EQ.TAU .OR. D(2).EQ.TAU .OR. D(3).EQ.TAU ) THEN
00152 TAU = ZERO
00153 ELSE
00154 TEMP = FINIT + TAU*Z(1)/( D(1)*( D( 1 )-TAU ) ) +
00155 $ TAU*Z(2)/( D(2)*( D( 2 )-TAU ) ) +
00156 $ TAU*Z(3)/( D(3)*( D( 3 )-TAU ) )
00157 IF( TEMP .LE. ZERO )THEN
00158 LBD = TAU
00159 ELSE
00160 UBD = TAU
00161 END IF
00162 IF( ABS( FINIT ).LE.ABS( TEMP ) )
00163 $ TAU = ZERO
00164 END IF
00165 END IF
00166
00167
00168
00169
00170
00171
00172
00173 EPS = SLAMCH( 'Epsilon' )
00174 BASE = SLAMCH( 'Base' )
00175 SMALL1 = BASE**( INT( LOG( SLAMCH( 'SafMin' ) ) / LOG( BASE ) /
00176 $ THREE ) )
00177 SMINV1 = ONE / SMALL1
00178 SMALL2 = SMALL1*SMALL1
00179 SMINV2 = SMINV1*SMINV1
00180
00181
00182
00183
00184 IF( ORGATI ) THEN
00185 TEMP = MIN( ABS( D( 2 )-TAU ), ABS( D( 3 )-TAU ) )
00186 ELSE
00187 TEMP = MIN( ABS( D( 1 )-TAU ), ABS( D( 2 )-TAU ) )
00188 END IF
00189 SCALE = .FALSE.
00190 IF( TEMP.LE.SMALL1 ) THEN
00191 SCALE = .TRUE.
00192 IF( TEMP.LE.SMALL2 ) THEN
00193
00194
00195
00196 SCLFAC = SMINV2
00197 SCLINV = SMALL2
00198 ELSE
00199
00200
00201
00202 SCLFAC = SMINV1
00203 SCLINV = SMALL1
00204 END IF
00205
00206
00207
00208 DO 10 I = 1, 3
00209 DSCALE( I ) = D( I )*SCLFAC
00210 ZSCALE( I ) = Z( I )*SCLFAC
00211 10 CONTINUE
00212 TAU = TAU*SCLFAC
00213 LBD = LBD*SCLFAC
00214 UBD = UBD*SCLFAC
00215 ELSE
00216
00217
00218
00219 DO 20 I = 1, 3
00220 DSCALE( I ) = D( I )
00221 ZSCALE( I ) = Z( I )
00222 20 CONTINUE
00223 END IF
00224
00225 FC = ZERO
00226 DF = ZERO
00227 DDF = ZERO
00228 DO 30 I = 1, 3
00229 TEMP = ONE / ( DSCALE( I )-TAU )
00230 TEMP1 = ZSCALE( I )*TEMP
00231 TEMP2 = TEMP1*TEMP
00232 TEMP3 = TEMP2*TEMP
00233 FC = FC + TEMP1 / DSCALE( I )
00234 DF = DF + TEMP2
00235 DDF = DDF + TEMP3
00236 30 CONTINUE
00237 F = FINIT + TAU*FC
00238
00239 IF( ABS( F ).LE.ZERO )
00240 $ GO TO 60
00241 IF( F .LE. ZERO )THEN
00242 LBD = TAU
00243 ELSE
00244 UBD = TAU
00245 END IF
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 ITER = NITER + 1
00259
00260 DO 50 NITER = ITER, MAXIT
00261
00262 IF( ORGATI ) THEN
00263 TEMP1 = DSCALE( 2 ) - TAU
00264 TEMP2 = DSCALE( 3 ) - TAU
00265 ELSE
00266 TEMP1 = DSCALE( 1 ) - TAU
00267 TEMP2 = DSCALE( 2 ) - TAU
00268 END IF
00269 A = ( TEMP1+TEMP2 )*F - TEMP1*TEMP2*DF
00270 B = TEMP1*TEMP2*F
00271 C = F - ( TEMP1+TEMP2 )*DF + TEMP1*TEMP2*DDF
00272 TEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )
00273 A = A / TEMP
00274 B = B / TEMP
00275 C = C / TEMP
00276 IF( C.EQ.ZERO ) THEN
00277 ETA = B / A
00278 ELSE IF( A.LE.ZERO ) THEN
00279 ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
00280 ELSE
00281 ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
00282 END IF
00283 IF( F*ETA.GE.ZERO ) THEN
00284 ETA = -F / DF
00285 END IF
00286
00287 TAU = TAU + ETA
00288 IF( TAU .LT. LBD .OR. TAU .GT. UBD )
00289 $ TAU = ( LBD + UBD )/TWO
00290
00291 FC = ZERO
00292 ERRETM = ZERO
00293 DF = ZERO
00294 DDF = ZERO
00295 DO 40 I = 1, 3
00296 TEMP = ONE / ( DSCALE( I )-TAU )
00297 TEMP1 = ZSCALE( I )*TEMP
00298 TEMP2 = TEMP1*TEMP
00299 TEMP3 = TEMP2*TEMP
00300 TEMP4 = TEMP1 / DSCALE( I )
00301 FC = FC + TEMP4
00302 ERRETM = ERRETM + ABS( TEMP4 )
00303 DF = DF + TEMP2
00304 DDF = DDF + TEMP3
00305 40 CONTINUE
00306 F = FINIT + TAU*FC
00307 ERRETM = EIGHT*( ABS( FINIT )+ABS( TAU )*ERRETM ) +
00308 $ ABS( TAU )*DF
00309 IF( ABS( F ).LE.EPS*ERRETM )
00310 $ GO TO 60
00311 IF( F .LE. ZERO )THEN
00312 LBD = TAU
00313 ELSE
00314 UBD = TAU
00315 END IF
00316 50 CONTINUE
00317 INFO = 1
00318 60 CONTINUE
00319
00320
00321
00322 IF( SCALE )
00323 $ TAU = TAU*SCLINV
00324 RETURN
00325
00326
00327
00328 END