00001 SUBROUTINE SLASQ2( N, Z, INFO )
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 INTEGER INFO, N
00015
00016
00017 REAL Z( * )
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 REAL CBIAS
00076 PARAMETER ( CBIAS = 1.50E0 )
00077 REAL ZERO, HALF, ONE, TWO, FOUR, HUNDRD
00078 PARAMETER ( ZERO = 0.0E0, HALF = 0.5E0, ONE = 1.0E0,
00079 $ TWO = 2.0E0, FOUR = 4.0E0, HUNDRD = 100.0E0 )
00080
00081
00082 LOGICAL IEEE
00083 INTEGER I0, I4, IINFO, IPN4, ITER, IWHILA, IWHILB, K,
00084 $ KMIN, N0, NBIG, NDIV, NFAIL, PP, SPLT, TTYPE
00085 REAL D, DEE, DEEMIN, DESIG, DMIN, DMIN1, DMIN2, DN,
00086 $ DN1, DN2, E, EMAX, EMIN, EPS, G, OLDEMN, QMAX,
00087 $ QMIN, S, SAFMIN, SIGMA, T, TAU, TEMP, TOL,
00088 $ TOL2, TRACE, ZMAX
00089
00090
00091 EXTERNAL SLASQ3, SLASRT, XERBLA
00092
00093
00094 INTEGER ILAENV
00095 REAL SLAMCH
00096 EXTERNAL ILAENV, SLAMCH
00097
00098
00099 INTRINSIC ABS, MAX, MIN, REAL, SQRT
00100
00101
00102
00103
00104
00105
00106 INFO = 0
00107 EPS = SLAMCH( 'Precision' )
00108 SAFMIN = SLAMCH( 'Safe minimum' )
00109 TOL = EPS*HUNDRD
00110 TOL2 = TOL**2
00111
00112 IF( N.LT.0 ) THEN
00113 INFO = -1
00114 CALL XERBLA( 'SLASQ2', 1 )
00115 RETURN
00116 ELSE IF( N.EQ.0 ) THEN
00117 RETURN
00118 ELSE IF( N.EQ.1 ) THEN
00119
00120
00121
00122 IF( Z( 1 ).LT.ZERO ) THEN
00123 INFO = -201
00124 CALL XERBLA( 'SLASQ2', 2 )
00125 END IF
00126 RETURN
00127 ELSE IF( N.EQ.2 ) THEN
00128
00129
00130
00131 IF( Z( 2 ).LT.ZERO .OR. Z( 3 ).LT.ZERO ) THEN
00132 INFO = -2
00133 CALL XERBLA( 'SLASQ2', 2 )
00134 RETURN
00135 ELSE IF( Z( 3 ).GT.Z( 1 ) ) THEN
00136 D = Z( 3 )
00137 Z( 3 ) = Z( 1 )
00138 Z( 1 ) = D
00139 END IF
00140 Z( 5 ) = Z( 1 ) + Z( 2 ) + Z( 3 )
00141 IF( Z( 2 ).GT.Z( 3 )*TOL2 ) THEN
00142 T = HALF*( ( Z( 1 )-Z( 3 ) )+Z( 2 ) )
00143 S = Z( 3 )*( Z( 2 ) / T )
00144 IF( S.LE.T ) THEN
00145 S = Z( 3 )*( Z( 2 ) / ( T*( ONE+SQRT( ONE+S / T ) ) ) )
00146 ELSE
00147 S = Z( 3 )*( Z( 2 ) / ( T+SQRT( T )*SQRT( T+S ) ) )
00148 END IF
00149 T = Z( 1 ) + ( S+Z( 2 ) )
00150 Z( 3 ) = Z( 3 )*( Z( 1 ) / T )
00151 Z( 1 ) = T
00152 END IF
00153 Z( 2 ) = Z( 3 )
00154 Z( 6 ) = Z( 2 ) + Z( 1 )
00155 RETURN
00156 END IF
00157
00158
00159
00160 Z( 2*N ) = ZERO
00161 EMIN = Z( 2 )
00162 QMAX = ZERO
00163 ZMAX = ZERO
00164 D = ZERO
00165 E = ZERO
00166
00167 DO 10 K = 1, 2*( N-1 ), 2
00168 IF( Z( K ).LT.ZERO ) THEN
00169 INFO = -( 200+K )
00170 CALL XERBLA( 'SLASQ2', 2 )
00171 RETURN
00172 ELSE IF( Z( K+1 ).LT.ZERO ) THEN
00173 INFO = -( 200+K+1 )
00174 CALL XERBLA( 'SLASQ2', 2 )
00175 RETURN
00176 END IF
00177 D = D + Z( K )
00178 E = E + Z( K+1 )
00179 QMAX = MAX( QMAX, Z( K ) )
00180 EMIN = MIN( EMIN, Z( K+1 ) )
00181 ZMAX = MAX( QMAX, ZMAX, Z( K+1 ) )
00182 10 CONTINUE
00183 IF( Z( 2*N-1 ).LT.ZERO ) THEN
00184 INFO = -( 200+2*N-1 )
00185 CALL XERBLA( 'SLASQ2', 2 )
00186 RETURN
00187 END IF
00188 D = D + Z( 2*N-1 )
00189 QMAX = MAX( QMAX, Z( 2*N-1 ) )
00190 ZMAX = MAX( QMAX, ZMAX )
00191
00192
00193
00194 IF( E.EQ.ZERO ) THEN
00195 DO 20 K = 2, N
00196 Z( K ) = Z( 2*K-1 )
00197 20 CONTINUE
00198 CALL SLASRT( 'D', N, Z, IINFO )
00199 Z( 2*N-1 ) = D
00200 RETURN
00201 END IF
00202
00203 TRACE = D + E
00204
00205
00206
00207 IF( TRACE.EQ.ZERO ) THEN
00208 Z( 2*N-1 ) = ZERO
00209 RETURN
00210 END IF
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 IEEE = .FALSE.
00221
00222
00223
00224 DO 30 K = 2*N, 2, -2
00225 Z( 2*K ) = ZERO
00226 Z( 2*K-1 ) = Z( K )
00227 Z( 2*K-2 ) = ZERO
00228 Z( 2*K-3 ) = Z( K-1 )
00229 30 CONTINUE
00230
00231 I0 = 1
00232 N0 = N
00233
00234
00235
00236 IF( CBIAS*Z( 4*I0-3 ).LT.Z( 4*N0-3 ) ) THEN
00237 IPN4 = 4*( I0+N0 )
00238 DO 40 I4 = 4*I0, 2*( I0+N0-1 ), 4
00239 TEMP = Z( I4-3 )
00240 Z( I4-3 ) = Z( IPN4-I4-3 )
00241 Z( IPN4-I4-3 ) = TEMP
00242 TEMP = Z( I4-1 )
00243 Z( I4-1 ) = Z( IPN4-I4-5 )
00244 Z( IPN4-I4-5 ) = TEMP
00245 40 CONTINUE
00246 END IF
00247
00248
00249
00250 PP = 0
00251
00252 DO 80 K = 1, 2
00253
00254 D = Z( 4*N0+PP-3 )
00255 DO 50 I4 = 4*( N0-1 ) + PP, 4*I0 + PP, -4
00256 IF( Z( I4-1 ).LE.TOL2*D ) THEN
00257 Z( I4-1 ) = -ZERO
00258 D = Z( I4-3 )
00259 ELSE
00260 D = Z( I4-3 )*( D / ( D+Z( I4-1 ) ) )
00261 END IF
00262 50 CONTINUE
00263
00264
00265
00266 EMIN = Z( 4*I0+PP+1 )
00267 D = Z( 4*I0+PP-3 )
00268 DO 60 I4 = 4*I0 + PP, 4*( N0-1 ) + PP, 4
00269 Z( I4-2*PP-2 ) = D + Z( I4-1 )
00270 IF( Z( I4-1 ).LE.TOL2*D ) THEN
00271 Z( I4-1 ) = -ZERO
00272 Z( I4-2*PP-2 ) = D
00273 Z( I4-2*PP ) = ZERO
00274 D = Z( I4+1 )
00275 ELSE IF( SAFMIN*Z( I4+1 ).LT.Z( I4-2*PP-2 ) .AND.
00276 $ SAFMIN*Z( I4-2*PP-2 ).LT.Z( I4+1 ) ) THEN
00277 TEMP = Z( I4+1 ) / Z( I4-2*PP-2 )
00278 Z( I4-2*PP ) = Z( I4-1 )*TEMP
00279 D = D*TEMP
00280 ELSE
00281 Z( I4-2*PP ) = Z( I4+1 )*( Z( I4-1 ) / Z( I4-2*PP-2 ) )
00282 D = Z( I4+1 )*( D / Z( I4-2*PP-2 ) )
00283 END IF
00284 EMIN = MIN( EMIN, Z( I4-2*PP ) )
00285 60 CONTINUE
00286 Z( 4*N0-PP-2 ) = D
00287
00288
00289
00290 QMAX = Z( 4*I0-PP-2 )
00291 DO 70 I4 = 4*I0 - PP + 2, 4*N0 - PP - 2, 4
00292 QMAX = MAX( QMAX, Z( I4 ) )
00293 70 CONTINUE
00294
00295
00296
00297 PP = 1 - PP
00298 80 CONTINUE
00299
00300
00301
00302 TTYPE = 0
00303 DMIN1 = ZERO
00304 DMIN2 = ZERO
00305 DN = ZERO
00306 DN1 = ZERO
00307 DN2 = ZERO
00308 G = ZERO
00309 TAU = ZERO
00310
00311 ITER = 2
00312 NFAIL = 0
00313 NDIV = 2*( N0-I0 )
00314
00315 DO 160 IWHILA = 1, N + 1
00316 IF( N0.LT.1 )
00317 $ GO TO 170
00318
00319
00320
00321
00322
00323
00324 DESIG = ZERO
00325 IF( N0.EQ.N ) THEN
00326 SIGMA = ZERO
00327 ELSE
00328 SIGMA = -Z( 4*N0-1 )
00329 END IF
00330 IF( SIGMA.LT.ZERO ) THEN
00331 INFO = 1
00332 RETURN
00333 END IF
00334
00335
00336
00337
00338 EMAX = ZERO
00339 IF( N0.GT.I0 ) THEN
00340 EMIN = ABS( Z( 4*N0-5 ) )
00341 ELSE
00342 EMIN = ZERO
00343 END IF
00344 QMIN = Z( 4*N0-3 )
00345 QMAX = QMIN
00346 DO 90 I4 = 4*N0, 8, -4
00347 IF( Z( I4-5 ).LE.ZERO )
00348 $ GO TO 100
00349 IF( QMIN.GE.FOUR*EMAX ) THEN
00350 QMIN = MIN( QMIN, Z( I4-3 ) )
00351 EMAX = MAX( EMAX, Z( I4-5 ) )
00352 END IF
00353 QMAX = MAX( QMAX, Z( I4-7 )+Z( I4-5 ) )
00354 EMIN = MIN( EMIN, Z( I4-5 ) )
00355 90 CONTINUE
00356 I4 = 4
00357
00358 100 CONTINUE
00359 I0 = I4 / 4
00360 PP = 0
00361
00362 IF( N0-I0.GT.1 ) THEN
00363 DEE = Z( 4*I0-3 )
00364 DEEMIN = DEE
00365 KMIN = I0
00366 DO 110 I4 = 4*I0+1, 4*N0-3, 4
00367 DEE = Z( I4 )*( DEE /( DEE+Z( I4-2 ) ) )
00368 IF( DEE.LE.DEEMIN ) THEN
00369 DEEMIN = DEE
00370 KMIN = ( I4+3 )/4
00371 END IF
00372 110 CONTINUE
00373 IF( (KMIN-I0)*2.LT.N0-KMIN .AND.
00374 $ DEEMIN.LE.HALF*Z(4*N0-3) ) THEN
00375 IPN4 = 4*( I0+N0 )
00376 PP = 2
00377 DO 120 I4 = 4*I0, 2*( I0+N0-1 ), 4
00378 TEMP = Z( I4-3 )
00379 Z( I4-3 ) = Z( IPN4-I4-3 )
00380 Z( IPN4-I4-3 ) = TEMP
00381 TEMP = Z( I4-2 )
00382 Z( I4-2 ) = Z( IPN4-I4-2 )
00383 Z( IPN4-I4-2 ) = TEMP
00384 TEMP = Z( I4-1 )
00385 Z( I4-1 ) = Z( IPN4-I4-5 )
00386 Z( IPN4-I4-5 ) = TEMP
00387 TEMP = Z( I4 )
00388 Z( I4 ) = Z( IPN4-I4-4 )
00389 Z( IPN4-I4-4 ) = TEMP
00390 120 CONTINUE
00391 END IF
00392 END IF
00393
00394
00395
00396 DMIN = -MAX( ZERO, QMIN-TWO*SQRT( QMIN )*SQRT( EMAX ) )
00397
00398
00399
00400
00401
00402
00403
00404 NBIG = 30*( N0-I0+1 )
00405 DO 140 IWHILB = 1, NBIG
00406 IF( I0.GT.N0 )
00407 $ GO TO 150
00408
00409
00410
00411 CALL SLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,
00412 $ ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,
00413 $ DN2, G, TAU )
00414
00415 PP = 1 - PP
00416
00417
00418
00419 IF( PP.EQ.0 .AND. N0-I0.GE.3 ) THEN
00420 IF( Z( 4*N0 ).LE.TOL2*QMAX .OR.
00421 $ Z( 4*N0-1 ).LE.TOL2*SIGMA ) THEN
00422 SPLT = I0 - 1
00423 QMAX = Z( 4*I0-3 )
00424 EMIN = Z( 4*I0-1 )
00425 OLDEMN = Z( 4*I0 )
00426 DO 130 I4 = 4*I0, 4*( N0-3 ), 4
00427 IF( Z( I4 ).LE.TOL2*Z( I4-3 ) .OR.
00428 $ Z( I4-1 ).LE.TOL2*SIGMA ) THEN
00429 Z( I4-1 ) = -SIGMA
00430 SPLT = I4 / 4
00431 QMAX = ZERO
00432 EMIN = Z( I4+3 )
00433 OLDEMN = Z( I4+4 )
00434 ELSE
00435 QMAX = MAX( QMAX, Z( I4+1 ) )
00436 EMIN = MIN( EMIN, Z( I4-1 ) )
00437 OLDEMN = MIN( OLDEMN, Z( I4 ) )
00438 END IF
00439 130 CONTINUE
00440 Z( 4*N0-1 ) = EMIN
00441 Z( 4*N0 ) = OLDEMN
00442 I0 = SPLT + 1
00443 END IF
00444 END IF
00445
00446 140 CONTINUE
00447
00448 INFO = 2
00449 RETURN
00450
00451
00452
00453 150 CONTINUE
00454
00455 160 CONTINUE
00456
00457 INFO = 3
00458 RETURN
00459
00460
00461
00462 170 CONTINUE
00463
00464
00465
00466 DO 180 K = 2, N
00467 Z( K ) = Z( 4*K-3 )
00468 180 CONTINUE
00469
00470
00471
00472 CALL SLASRT( 'D', N, Z, IINFO )
00473
00474 E = ZERO
00475 DO 190 K = N, 1, -1
00476 E = E + Z( K )
00477 190 CONTINUE
00478
00479
00480
00481 Z( 2*N+1 ) = TRACE
00482 Z( 2*N+2 ) = E
00483 Z( 2*N+3 ) = REAL( ITER )
00484 Z( 2*N+4 ) = REAL( NDIV ) / REAL( N**2 )
00485 Z( 2*N+5 ) = HUNDRD*NFAIL / REAL( ITER )
00486 RETURN
00487
00488
00489
00490 END