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