00001 SUBROUTINE ZHPTRI( UPLO, N, AP, IPIV, WORK, INFO )
00002
00003
00004
00005
00006
00007
00008
00009 CHARACTER UPLO
00010 INTEGER INFO, N
00011
00012
00013 INTEGER IPIV( * )
00014 COMPLEX*16 AP( * ), WORK( * )
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 DOUBLE PRECISION ONE
00064 COMPLEX*16 CONE, ZERO
00065 PARAMETER ( ONE = 1.0D+0, CONE = ( 1.0D+0, 0.0D+0 ),
00066 $ ZERO = ( 0.0D+0, 0.0D+0 ) )
00067
00068
00069 LOGICAL UPPER
00070 INTEGER J, K, KC, KCNEXT, KP, KPC, KSTEP, KX, NPP
00071 DOUBLE PRECISION AK, AKP1, D, T
00072 COMPLEX*16 AKKP1, TEMP
00073
00074
00075 LOGICAL LSAME
00076 COMPLEX*16 ZDOTC
00077 EXTERNAL LSAME, ZDOTC
00078
00079
00080 EXTERNAL XERBLA, ZCOPY, ZHPMV, ZSWAP
00081
00082
00083 INTRINSIC ABS, DBLE, DCONJG
00084
00085
00086
00087
00088
00089 INFO = 0
00090 UPPER = LSAME( UPLO, 'U' )
00091 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00092 INFO = -1
00093 ELSE IF( N.LT.0 ) THEN
00094 INFO = -2
00095 END IF
00096 IF( INFO.NE.0 ) THEN
00097 CALL XERBLA( 'ZHPTRI', -INFO )
00098 RETURN
00099 END IF
00100
00101
00102
00103 IF( N.EQ.0 )
00104 $ RETURN
00105
00106
00107
00108 IF( UPPER ) THEN
00109
00110
00111
00112 KP = N*( N+1 ) / 2
00113 DO 10 INFO = N, 1, -1
00114 IF( IPIV( INFO ).GT.0 .AND. AP( KP ).EQ.ZERO )
00115 $ RETURN
00116 KP = KP - INFO
00117 10 CONTINUE
00118 ELSE
00119
00120
00121
00122 KP = 1
00123 DO 20 INFO = 1, N
00124 IF( IPIV( INFO ).GT.0 .AND. AP( KP ).EQ.ZERO )
00125 $ RETURN
00126 KP = KP + N - INFO + 1
00127 20 CONTINUE
00128 END IF
00129 INFO = 0
00130
00131 IF( UPPER ) THEN
00132
00133
00134
00135
00136
00137
00138 K = 1
00139 KC = 1
00140 30 CONTINUE
00141
00142
00143
00144 IF( K.GT.N )
00145 $ GO TO 50
00146
00147 KCNEXT = KC + K
00148 IF( IPIV( K ).GT.0 ) THEN
00149
00150
00151
00152
00153
00154 AP( KC+K-1 ) = ONE / DBLE( AP( KC+K-1 ) )
00155
00156
00157
00158 IF( K.GT.1 ) THEN
00159 CALL ZCOPY( K-1, AP( KC ), 1, WORK, 1 )
00160 CALL ZHPMV( UPLO, K-1, -CONE, AP, WORK, 1, ZERO,
00161 $ AP( KC ), 1 )
00162 AP( KC+K-1 ) = AP( KC+K-1 ) -
00163 $ DBLE( ZDOTC( K-1, WORK, 1, AP( KC ), 1 ) )
00164 END IF
00165 KSTEP = 1
00166 ELSE
00167
00168
00169
00170
00171
00172 T = ABS( AP( KCNEXT+K-1 ) )
00173 AK = DBLE( AP( KC+K-1 ) ) / T
00174 AKP1 = DBLE( AP( KCNEXT+K ) ) / T
00175 AKKP1 = AP( KCNEXT+K-1 ) / T
00176 D = T*( AK*AKP1-ONE )
00177 AP( KC+K-1 ) = AKP1 / D
00178 AP( KCNEXT+K ) = AK / D
00179 AP( KCNEXT+K-1 ) = -AKKP1 / D
00180
00181
00182
00183 IF( K.GT.1 ) THEN
00184 CALL ZCOPY( K-1, AP( KC ), 1, WORK, 1 )
00185 CALL ZHPMV( UPLO, K-1, -CONE, AP, WORK, 1, ZERO,
00186 $ AP( KC ), 1 )
00187 AP( KC+K-1 ) = AP( KC+K-1 ) -
00188 $ DBLE( ZDOTC( K-1, WORK, 1, AP( KC ), 1 ) )
00189 AP( KCNEXT+K-1 ) = AP( KCNEXT+K-1 ) -
00190 $ ZDOTC( K-1, AP( KC ), 1, AP( KCNEXT ),
00191 $ 1 )
00192 CALL ZCOPY( K-1, AP( KCNEXT ), 1, WORK, 1 )
00193 CALL ZHPMV( UPLO, K-1, -CONE, AP, WORK, 1, ZERO,
00194 $ AP( KCNEXT ), 1 )
00195 AP( KCNEXT+K ) = AP( KCNEXT+K ) -
00196 $ DBLE( ZDOTC( K-1, WORK, 1, AP( KCNEXT ),
00197 $ 1 ) )
00198 END IF
00199 KSTEP = 2
00200 KCNEXT = KCNEXT + K + 1
00201 END IF
00202
00203 KP = ABS( IPIV( K ) )
00204 IF( KP.NE.K ) THEN
00205
00206
00207
00208
00209 KPC = ( KP-1 )*KP / 2 + 1
00210 CALL ZSWAP( KP-1, AP( KC ), 1, AP( KPC ), 1 )
00211 KX = KPC + KP - 1
00212 DO 40 J = KP + 1, K - 1
00213 KX = KX + J - 1
00214 TEMP = DCONJG( AP( KC+J-1 ) )
00215 AP( KC+J-1 ) = DCONJG( AP( KX ) )
00216 AP( KX ) = TEMP
00217 40 CONTINUE
00218 AP( KC+KP-1 ) = DCONJG( AP( KC+KP-1 ) )
00219 TEMP = AP( KC+K-1 )
00220 AP( KC+K-1 ) = AP( KPC+KP-1 )
00221 AP( KPC+KP-1 ) = TEMP
00222 IF( KSTEP.EQ.2 ) THEN
00223 TEMP = AP( KC+K+K-1 )
00224 AP( KC+K+K-1 ) = AP( KC+K+KP-1 )
00225 AP( KC+K+KP-1 ) = TEMP
00226 END IF
00227 END IF
00228
00229 K = K + KSTEP
00230 KC = KCNEXT
00231 GO TO 30
00232 50 CONTINUE
00233
00234 ELSE
00235
00236
00237
00238
00239
00240
00241 NPP = N*( N+1 ) / 2
00242 K = N
00243 KC = NPP
00244 60 CONTINUE
00245
00246
00247
00248 IF( K.LT.1 )
00249 $ GO TO 80
00250
00251 KCNEXT = KC - ( N-K+2 )
00252 IF( IPIV( K ).GT.0 ) THEN
00253
00254
00255
00256
00257
00258 AP( KC ) = ONE / DBLE( AP( KC ) )
00259
00260
00261
00262 IF( K.LT.N ) THEN
00263 CALL ZCOPY( N-K, AP( KC+1 ), 1, WORK, 1 )
00264 CALL ZHPMV( UPLO, N-K, -CONE, AP( KC+N-K+1 ), WORK, 1,
00265 $ ZERO, AP( KC+1 ), 1 )
00266 AP( KC ) = AP( KC ) - DBLE( ZDOTC( N-K, WORK, 1,
00267 $ AP( KC+1 ), 1 ) )
00268 END IF
00269 KSTEP = 1
00270 ELSE
00271
00272
00273
00274
00275
00276 T = ABS( AP( KCNEXT+1 ) )
00277 AK = DBLE( AP( KCNEXT ) ) / T
00278 AKP1 = DBLE( AP( KC ) ) / T
00279 AKKP1 = AP( KCNEXT+1 ) / T
00280 D = T*( AK*AKP1-ONE )
00281 AP( KCNEXT ) = AKP1 / D
00282 AP( KC ) = AK / D
00283 AP( KCNEXT+1 ) = -AKKP1 / D
00284
00285
00286
00287 IF( K.LT.N ) THEN
00288 CALL ZCOPY( N-K, AP( KC+1 ), 1, WORK, 1 )
00289 CALL ZHPMV( UPLO, N-K, -CONE, AP( KC+( N-K+1 ) ), WORK,
00290 $ 1, ZERO, AP( KC+1 ), 1 )
00291 AP( KC ) = AP( KC ) - DBLE( ZDOTC( N-K, WORK, 1,
00292 $ AP( KC+1 ), 1 ) )
00293 AP( KCNEXT+1 ) = AP( KCNEXT+1 ) -
00294 $ ZDOTC( N-K, AP( KC+1 ), 1,
00295 $ AP( KCNEXT+2 ), 1 )
00296 CALL ZCOPY( N-K, AP( KCNEXT+2 ), 1, WORK, 1 )
00297 CALL ZHPMV( UPLO, N-K, -CONE, AP( KC+( N-K+1 ) ), WORK,
00298 $ 1, ZERO, AP( KCNEXT+2 ), 1 )
00299 AP( KCNEXT ) = AP( KCNEXT ) -
00300 $ DBLE( ZDOTC( N-K, WORK, 1, AP( KCNEXT+2 ),
00301 $ 1 ) )
00302 END IF
00303 KSTEP = 2
00304 KCNEXT = KCNEXT - ( N-K+3 )
00305 END IF
00306
00307 KP = ABS( IPIV( K ) )
00308 IF( KP.NE.K ) THEN
00309
00310
00311
00312
00313 KPC = NPP - ( N-KP+1 )*( N-KP+2 ) / 2 + 1
00314 IF( KP.LT.N )
00315 $ CALL ZSWAP( N-KP, AP( KC+KP-K+1 ), 1, AP( KPC+1 ), 1 )
00316 KX = KC + KP - K
00317 DO 70 J = K + 1, KP - 1
00318 KX = KX + N - J + 1
00319 TEMP = DCONJG( AP( KC+J-K ) )
00320 AP( KC+J-K ) = DCONJG( AP( KX ) )
00321 AP( KX ) = TEMP
00322 70 CONTINUE
00323 AP( KC+KP-K ) = DCONJG( AP( KC+KP-K ) )
00324 TEMP = AP( KC )
00325 AP( KC ) = AP( KPC )
00326 AP( KPC ) = TEMP
00327 IF( KSTEP.EQ.2 ) THEN
00328 TEMP = AP( KC-N+K-1 )
00329 AP( KC-N+K-1 ) = AP( KC-N+KP-1 )
00330 AP( KC-N+KP-1 ) = TEMP
00331 END IF
00332 END IF
00333
00334 K = K - KSTEP
00335 KC = KCNEXT
00336 GO TO 60
00337 80 CONTINUE
00338 END IF
00339
00340 RETURN
00341
00342
00343
00344 END