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