114
115
116
117
118
119
120 CHARACTER UPLO
121 INTEGER INFO, LDA, N
122
123
124 INTEGER IPIV( * )
125 COMPLEX A( LDA, * ), WORK( * )
126
127
128
129
130
131 COMPLEX ONE, ZERO
132 parameter( one = ( 1.0e+0, 0.0e+0 ),
133 $ zero = ( 0.0e+0, 0.0e+0 ) )
134
135
136 LOGICAL UPPER
137 INTEGER K, KP, KSTEP
138 COMPLEX AK, AKKP1, AKP1, D, T, TEMP
139
140
141 LOGICAL LSAME
142 COMPLEX CDOTU
144
145
147
148
149 INTRINSIC abs, max
150
151
152
153
154
155 info = 0
156 upper =
lsame( uplo,
'U' )
157 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
158 info = -1
159 ELSE IF( n.LT.0 ) THEN
160 info = -2
161 ELSE IF( lda.LT.max( 1, n ) ) THEN
162 info = -4
163 END IF
164 IF( info.NE.0 ) THEN
165 CALL xerbla(
'CSYTRI', -info )
166 RETURN
167 END IF
168
169
170
171 IF( n.EQ.0 )
172 $ RETURN
173
174
175
176 IF( upper ) THEN
177
178
179
180 DO 10 info = n, 1, -1
181 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.zero )
182 $ RETURN
183 10 CONTINUE
184 ELSE
185
186
187
188 DO 20 info = 1, n
189 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.zero )
190 $ RETURN
191 20 CONTINUE
192 END IF
193 info = 0
194
195 IF( upper ) THEN
196
197
198
199
200
201
202 k = 1
203 30 CONTINUE
204
205
206
207 IF( k.GT.n )
208 $ GO TO 40
209
210 IF( ipiv( k ).GT.0 ) THEN
211
212
213
214
215
216 a( k, k ) = one / a( k, k )
217
218
219
220 IF( k.GT.1 ) THEN
221 CALL ccopy( k-1, a( 1, k ), 1, work, 1 )
222 CALL csymv( uplo, k-1, -one, a, lda, work, 1, zero,
223 $ a( 1, k ), 1 )
224 a( k, k ) = a( k, k ) -
cdotu( k-1, work, 1, a( 1, k ),
225 $ 1 )
226 END IF
227 kstep = 1
228 ELSE
229
230
231
232
233
234 t = a( k, k+1 )
235 ak = a( k, k ) / t
236 akp1 = a( k+1, k+1 ) / t
237 akkp1 = a( k, k+1 ) / t
238 d = t*( ak*akp1-one )
239 a( k, k ) = akp1 / d
240 a( k+1, k+1 ) = ak / d
241 a( k, k+1 ) = -akkp1 / d
242
243
244
245 IF( k.GT.1 ) THEN
246 CALL ccopy( k-1, a( 1, k ), 1, work, 1 )
247 CALL csymv( uplo, k-1, -one, a, lda, work, 1, zero,
248 $ a( 1, k ), 1 )
249 a( k, k ) = a( k, k ) -
cdotu( k-1, work, 1, a( 1, k ),
250 $ 1 )
251 a( k, k+1 ) = a( k, k+1 ) -
252 $
cdotu( k-1, a( 1, k ), 1, a( 1, k+1 ), 1 )
253 CALL ccopy( k-1, a( 1, k+1 ), 1, work, 1 )
254 CALL csymv( uplo, k-1, -one, a, lda, work, 1, zero,
255 $ a( 1, k+1 ), 1 )
256 a( k+1, k+1 ) = a( k+1, k+1 ) -
257 $
cdotu( k-1, work, 1, a( 1, k+1 ), 1 )
258 END IF
259 kstep = 2
260 END IF
261
262 kp = abs( ipiv( k ) )
263 IF( kp.NE.k ) THEN
264
265
266
267
268 CALL cswap( kp-1, a( 1, k ), 1, a( 1, kp ), 1 )
269 CALL cswap( k-kp-1, a( kp+1, k ), 1, a( kp, kp+1 ), lda )
270 temp = a( k, k )
271 a( k, k ) = a( kp, kp )
272 a( kp, kp ) = temp
273 IF( kstep.EQ.2 ) THEN
274 temp = a( k, k+1 )
275 a( k, k+1 ) = a( kp, k+1 )
276 a( kp, k+1 ) = temp
277 END IF
278 END IF
279
280 k = k + kstep
281 GO TO 30
282 40 CONTINUE
283
284 ELSE
285
286
287
288
289
290
291 k = n
292 50 CONTINUE
293
294
295
296 IF( k.LT.1 )
297 $ GO TO 60
298
299 IF( ipiv( k ).GT.0 ) THEN
300
301
302
303
304
305 a( k, k ) = one / a( k, k )
306
307
308
309 IF( k.LT.n ) THEN
310 CALL ccopy( n-k, a( k+1, k ), 1, work, 1 )
311 CALL csymv( uplo, n-k, -one, a( k+1, k+1 ), lda, work, 1,
312 $ zero, a( k+1, k ), 1 )
313 a( k, k ) = a( k, k ) -
cdotu( n-k, work, 1, a( k+1, k ),
314 $ 1 )
315 END IF
316 kstep = 1
317 ELSE
318
319
320
321
322
323 t = a( k, k-1 )
324 ak = a( k-1, k-1 ) / t
325 akp1 = a( k, k ) / t
326 akkp1 = a( k, k-1 ) / t
327 d = t*( ak*akp1-one )
328 a( k-1, k-1 ) = akp1 / d
329 a( k, k ) = ak / d
330 a( k, k-1 ) = -akkp1 / d
331
332
333
334 IF( k.LT.n ) THEN
335 CALL ccopy( n-k, a( k+1, k ), 1, work, 1 )
336 CALL csymv( uplo, n-k, -one, a( k+1, k+1 ), lda, work, 1,
337 $ zero, a( k+1, k ), 1 )
338 a( k, k ) = a( k, k ) -
cdotu( n-k, work, 1, a( k+1, k ),
339 $ 1 )
340 a( k, k-1 ) = a( k, k-1 ) -
341 $
cdotu( n-k, a( k+1, k ), 1, a( k+1, k-1 ),
342 $ 1 )
343 CALL ccopy( n-k, a( k+1, k-1 ), 1, work, 1 )
344 CALL csymv( uplo, n-k, -one, a( k+1, k+1 ), lda, work, 1,
345 $ zero, a( k+1, k-1 ), 1 )
346 a( k-1, k-1 ) = a( k-1, k-1 ) -
347 $
cdotu( n-k, work, 1, a( k+1, k-1 ), 1 )
348 END IF
349 kstep = 2
350 END IF
351
352 kp = abs( ipiv( k ) )
353 IF( kp.NE.k ) THEN
354
355
356
357
358 IF( kp.LT.n )
359 $
CALL cswap( n-kp, a( kp+1, k ), 1, a( kp+1, kp ), 1 )
360 CALL cswap( kp-k-1, a( k+1, k ), 1, a( kp, k+1 ), lda )
361 temp = a( k, k )
362 a( k, k ) = a( kp, kp )
363 a( kp, kp ) = temp
364 IF( kstep.EQ.2 ) THEN
365 temp = a( k, k-1 )
366 a( k, k-1 ) = a( kp, k-1 )
367 a( kp, k-1 ) = temp
368 END IF
369 END IF
370
371 k = k - kstep
372 GO TO 50
373 60 CONTINUE
374 END IF
375
376 RETURN
377
378
379
subroutine xerbla(srname, info)
subroutine ccopy(n, cx, incx, cy, incy)
CCOPY
complex function cdotu(n, cx, incx, cy, incy)
CDOTU
subroutine csymv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
CSYMV computes a matrix-vector product for a complex symmetric matrix.
logical function lsame(ca, cb)
LSAME
subroutine cswap(n, cx, incx, cy, incy)
CSWAP