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