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