00001 SUBROUTINE DSPTRF( UPLO, N, AP, IPIV, INFO )
00002
00003
00004
00005
00006
00007
00008
00009 CHARACTER UPLO
00010 INTEGER INFO, N
00011
00012
00013 INTEGER IPIV( * )
00014 DOUBLE PRECISION AP( * )
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
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 DOUBLE PRECISION ZERO, ONE
00112 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
00113 DOUBLE PRECISION EIGHT, SEVTEN
00114 PARAMETER ( EIGHT = 8.0D+0, SEVTEN = 17.0D+0 )
00115
00116
00117 LOGICAL UPPER
00118 INTEGER I, IMAX, J, JMAX, K, KC, KK, KNC, KP, KPC,
00119 $ KSTEP, KX, NPP
00120 DOUBLE PRECISION ABSAKK, ALPHA, COLMAX, D11, D12, D21, D22, R1,
00121 $ ROWMAX, T, WK, WKM1, WKP1
00122
00123
00124 LOGICAL LSAME
00125 INTEGER IDAMAX
00126 EXTERNAL LSAME, IDAMAX
00127
00128
00129 EXTERNAL DSCAL, DSPR, DSWAP, XERBLA
00130
00131
00132 INTRINSIC ABS, MAX, SQRT
00133
00134
00135
00136
00137
00138 INFO = 0
00139 UPPER = LSAME( UPLO, 'U' )
00140 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00141 INFO = -1
00142 ELSE IF( N.LT.0 ) THEN
00143 INFO = -2
00144 END IF
00145 IF( INFO.NE.0 ) THEN
00146 CALL XERBLA( 'DSPTRF', -INFO )
00147 RETURN
00148 END IF
00149
00150
00151
00152 ALPHA = ( ONE+SQRT( SEVTEN ) ) / EIGHT
00153
00154 IF( UPPER ) THEN
00155
00156
00157
00158
00159
00160
00161 K = N
00162 KC = ( N-1 )*N / 2 + 1
00163 10 CONTINUE
00164 KNC = KC
00165
00166
00167
00168 IF( K.LT.1 )
00169 $ GO TO 110
00170 KSTEP = 1
00171
00172
00173
00174
00175 ABSAKK = ABS( AP( KC+K-1 ) )
00176
00177
00178
00179
00180 IF( K.GT.1 ) THEN
00181 IMAX = IDAMAX( K-1, AP( KC ), 1 )
00182 COLMAX = ABS( AP( KC+IMAX-1 ) )
00183 ELSE
00184 COLMAX = ZERO
00185 END IF
00186
00187 IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN
00188
00189
00190
00191 IF( INFO.EQ.0 )
00192 $ INFO = K
00193 KP = K
00194 ELSE
00195 IF( ABSAKK.GE.ALPHA*COLMAX ) THEN
00196
00197
00198
00199 KP = K
00200 ELSE
00201
00202
00203
00204
00205 ROWMAX = ZERO
00206 JMAX = IMAX
00207 KX = IMAX*( IMAX+1 ) / 2 + IMAX
00208 DO 20 J = IMAX + 1, K
00209 IF( ABS( AP( KX ) ).GT.ROWMAX ) THEN
00210 ROWMAX = ABS( AP( KX ) )
00211 JMAX = J
00212 END IF
00213 KX = KX + J
00214 20 CONTINUE
00215 KPC = ( IMAX-1 )*IMAX / 2 + 1
00216 IF( IMAX.GT.1 ) THEN
00217 JMAX = IDAMAX( IMAX-1, AP( KPC ), 1 )
00218 ROWMAX = MAX( ROWMAX, ABS( AP( KPC+JMAX-1 ) ) )
00219 END IF
00220
00221 IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN
00222
00223
00224
00225 KP = K
00226 ELSE IF( ABS( AP( KPC+IMAX-1 ) ).GE.ALPHA*ROWMAX ) THEN
00227
00228
00229
00230
00231 KP = IMAX
00232 ELSE
00233
00234
00235
00236
00237 KP = IMAX
00238 KSTEP = 2
00239 END IF
00240 END IF
00241
00242 KK = K - KSTEP + 1
00243 IF( KSTEP.EQ.2 )
00244 $ KNC = KNC - K + 1
00245 IF( KP.NE.KK ) THEN
00246
00247
00248
00249
00250 CALL DSWAP( KP-1, AP( KNC ), 1, AP( KPC ), 1 )
00251 KX = KPC + KP - 1
00252 DO 30 J = KP + 1, KK - 1
00253 KX = KX + J - 1
00254 T = AP( KNC+J-1 )
00255 AP( KNC+J-1 ) = AP( KX )
00256 AP( KX ) = T
00257 30 CONTINUE
00258 T = AP( KNC+KK-1 )
00259 AP( KNC+KK-1 ) = AP( KPC+KP-1 )
00260 AP( KPC+KP-1 ) = T
00261 IF( KSTEP.EQ.2 ) THEN
00262 T = AP( KC+K-2 )
00263 AP( KC+K-2 ) = AP( KC+KP-1 )
00264 AP( KC+KP-1 ) = T
00265 END IF
00266 END IF
00267
00268
00269
00270 IF( KSTEP.EQ.1 ) THEN
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 R1 = ONE / AP( KC+K-1 )
00283 CALL DSPR( UPLO, K-1, -R1, AP( KC ), 1, AP )
00284
00285
00286
00287 CALL DSCAL( K-1, R1, AP( KC ), 1 )
00288 ELSE
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 IF( K.GT.2 ) THEN
00303
00304 D12 = AP( K-1+( K-1 )*K / 2 )
00305 D22 = AP( K-1+( K-2 )*( K-1 ) / 2 ) / D12
00306 D11 = AP( K+( K-1 )*K / 2 ) / D12
00307 T = ONE / ( D11*D22-ONE )
00308 D12 = T / D12
00309
00310 DO 50 J = K - 2, 1, -1
00311 WKM1 = D12*( D11*AP( J+( K-2 )*( K-1 ) / 2 )-
00312 $ AP( J+( K-1 )*K / 2 ) )
00313 WK = D12*( D22*AP( J+( K-1 )*K / 2 )-
00314 $ AP( J+( K-2 )*( K-1 ) / 2 ) )
00315 DO 40 I = J, 1, -1
00316 AP( I+( J-1 )*J / 2 ) = AP( I+( J-1 )*J / 2 ) -
00317 $ AP( I+( K-1 )*K / 2 )*WK -
00318 $ AP( I+( K-2 )*( K-1 ) / 2 )*WKM1
00319 40 CONTINUE
00320 AP( J+( K-1 )*K / 2 ) = WK
00321 AP( J+( K-2 )*( K-1 ) / 2 ) = WKM1
00322 50 CONTINUE
00323
00324 END IF
00325
00326 END IF
00327 END IF
00328
00329
00330
00331 IF( KSTEP.EQ.1 ) THEN
00332 IPIV( K ) = KP
00333 ELSE
00334 IPIV( K ) = -KP
00335 IPIV( K-1 ) = -KP
00336 END IF
00337
00338
00339
00340 K = K - KSTEP
00341 KC = KNC - K
00342 GO TO 10
00343
00344 ELSE
00345
00346
00347
00348
00349
00350
00351 K = 1
00352 KC = 1
00353 NPP = N*( N+1 ) / 2
00354 60 CONTINUE
00355 KNC = KC
00356
00357
00358
00359 IF( K.GT.N )
00360 $ GO TO 110
00361 KSTEP = 1
00362
00363
00364
00365
00366 ABSAKK = ABS( AP( KC ) )
00367
00368
00369
00370
00371 IF( K.LT.N ) THEN
00372 IMAX = K + IDAMAX( N-K, AP( KC+1 ), 1 )
00373 COLMAX = ABS( AP( KC+IMAX-K ) )
00374 ELSE
00375 COLMAX = ZERO
00376 END IF
00377
00378 IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN
00379
00380
00381
00382 IF( INFO.EQ.0 )
00383 $ INFO = K
00384 KP = K
00385 ELSE
00386 IF( ABSAKK.GE.ALPHA*COLMAX ) THEN
00387
00388
00389
00390 KP = K
00391 ELSE
00392
00393
00394
00395
00396 ROWMAX = ZERO
00397 KX = KC + IMAX - K
00398 DO 70 J = K, IMAX - 1
00399 IF( ABS( AP( KX ) ).GT.ROWMAX ) THEN
00400 ROWMAX = ABS( AP( KX ) )
00401 JMAX = J
00402 END IF
00403 KX = KX + N - J
00404 70 CONTINUE
00405 KPC = NPP - ( N-IMAX+1 )*( N-IMAX+2 ) / 2 + 1
00406 IF( IMAX.LT.N ) THEN
00407 JMAX = IMAX + IDAMAX( N-IMAX, AP( KPC+1 ), 1 )
00408 ROWMAX = MAX( ROWMAX, ABS( AP( KPC+JMAX-IMAX ) ) )
00409 END IF
00410
00411 IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN
00412
00413
00414
00415 KP = K
00416 ELSE IF( ABS( AP( KPC ) ).GE.ALPHA*ROWMAX ) THEN
00417
00418
00419
00420
00421 KP = IMAX
00422 ELSE
00423
00424
00425
00426
00427 KP = IMAX
00428 KSTEP = 2
00429 END IF
00430 END IF
00431
00432 KK = K + KSTEP - 1
00433 IF( KSTEP.EQ.2 )
00434 $ KNC = KNC + N - K + 1
00435 IF( KP.NE.KK ) THEN
00436
00437
00438
00439
00440 IF( KP.LT.N )
00441 $ CALL DSWAP( N-KP, AP( KNC+KP-KK+1 ), 1, AP( KPC+1 ),
00442 $ 1 )
00443 KX = KNC + KP - KK
00444 DO 80 J = KK + 1, KP - 1
00445 KX = KX + N - J + 1
00446 T = AP( KNC+J-KK )
00447 AP( KNC+J-KK ) = AP( KX )
00448 AP( KX ) = T
00449 80 CONTINUE
00450 T = AP( KNC )
00451 AP( KNC ) = AP( KPC )
00452 AP( KPC ) = T
00453 IF( KSTEP.EQ.2 ) THEN
00454 T = AP( KC+1 )
00455 AP( KC+1 ) = AP( KC+KP-K )
00456 AP( KC+KP-K ) = T
00457 END IF
00458 END IF
00459
00460
00461
00462 IF( KSTEP.EQ.1 ) THEN
00463
00464
00465
00466
00467
00468
00469
00470 IF( K.LT.N ) THEN
00471
00472
00473
00474
00475
00476 R1 = ONE / AP( KC )
00477 CALL DSPR( UPLO, N-K, -R1, AP( KC+1 ), 1,
00478 $ AP( KC+N-K+1 ) )
00479
00480
00481
00482 CALL DSCAL( N-K, R1, AP( KC+1 ), 1 )
00483 END IF
00484 ELSE
00485
00486
00487
00488
00489
00490
00491
00492
00493 IF( K.LT.N-1 ) THEN
00494
00495
00496
00497
00498
00499
00500 D21 = AP( K+1+( K-1 )*( 2*N-K ) / 2 )
00501 D11 = AP( K+1+K*( 2*N-K-1 ) / 2 ) / D21
00502 D22 = AP( K+( K-1 )*( 2*N-K ) / 2 ) / D21
00503 T = ONE / ( D11*D22-ONE )
00504 D21 = T / D21
00505
00506 DO 100 J = K + 2, N
00507 WK = D21*( D11*AP( J+( K-1 )*( 2*N-K ) / 2 )-
00508 $ AP( J+K*( 2*N-K-1 ) / 2 ) )
00509 WKP1 = D21*( D22*AP( J+K*( 2*N-K-1 ) / 2 )-
00510 $ AP( J+( K-1 )*( 2*N-K ) / 2 ) )
00511
00512 DO 90 I = J, N
00513 AP( I+( J-1 )*( 2*N-J ) / 2 ) = AP( I+( J-1 )*
00514 $ ( 2*N-J ) / 2 ) - AP( I+( K-1 )*( 2*N-K ) /
00515 $ 2 )*WK - AP( I+K*( 2*N-K-1 ) / 2 )*WKP1
00516 90 CONTINUE
00517
00518 AP( J+( K-1 )*( 2*N-K ) / 2 ) = WK
00519 AP( J+K*( 2*N-K-1 ) / 2 ) = WKP1
00520
00521 100 CONTINUE
00522 END IF
00523 END IF
00524 END IF
00525
00526
00527
00528 IF( KSTEP.EQ.1 ) THEN
00529 IPIV( K ) = KP
00530 ELSE
00531 IPIV( K ) = -KP
00532 IPIV( K+1 ) = -KP
00533 END IF
00534
00535
00536
00537 K = K + KSTEP
00538 KC = KNC + N - K + 2
00539 GO TO 60
00540
00541 END IF
00542
00543 110 CONTINUE
00544 RETURN
00545
00546
00547
00548 END