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