127
128
129
130
131
132
133 CHARACTER UPLO
134 INTEGER INFO, LDA, N
135
136
137 INTEGER IPIV( * )
138 COMPLEX A( LDA, * ), WORK( * )
139
140
141
142
143
144 COMPLEX CONE, CZERO
145 parameter( cone = ( 1.0e+0, 0.0e+0 ),
146 $ czero = ( 0.0e+0, 0.0e+0 ) )
147
148
149 LOGICAL UPPER
150 INTEGER K, KP, KSTEP
151 COMPLEX AK, AKKP1, AKP1, D, T, TEMP
152
153
154 LOGICAL LSAME
155 COMPLEX CDOTU
157
158
160
161
162 INTRINSIC max
163
164
165
166
167
168 info = 0
169 upper =
lsame( uplo,
'U' )
170 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
171 info = -1
172 ELSE IF( n.LT.0 ) THEN
173 info = -2
174 ELSE IF( lda.LT.max( 1, n ) ) THEN
175 info = -4
176 END IF
177 IF( info.NE.0 ) THEN
178 CALL xerbla(
'CSYTRI_ROOK', -info )
179 RETURN
180 END IF
181
182
183
184 IF( n.EQ.0 )
185 $ RETURN
186
187
188
189 IF( upper ) THEN
190
191
192
193 DO 10 info = n, 1, -1
194 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.czero )
195 $ RETURN
196 10 CONTINUE
197 ELSE
198
199
200
201 DO 20 info = 1, n
202 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.czero )
203 $ RETURN
204 20 CONTINUE
205 END IF
206 info = 0
207
208 IF( upper ) THEN
209
210
211
212
213
214
215 k = 1
216 30 CONTINUE
217
218
219
220 IF( k.GT.n )
221 $ GO TO 40
222
223 IF( ipiv( k ).GT.0 ) THEN
224
225
226
227
228
229 a( k, k ) = cone / a( k, k )
230
231
232
233 IF( k.GT.1 ) THEN
234 CALL ccopy( k-1, a( 1, k ), 1, work, 1 )
235 CALL csymv( uplo, k-1, -cone, a, lda, work, 1, czero,
236 $ a( 1, k ), 1 )
237 a( k, k ) = a( k, k ) -
cdotu( k-1, work, 1, a( 1,
238 $ k ),
239 $ 1 )
240 END IF
241 kstep = 1
242 ELSE
243
244
245
246
247
248 t = a( k, k+1 )
249 ak = a( k, k ) / t
250 akp1 = a( k+1, k+1 ) / t
251 akkp1 = a( k, k+1 ) / t
252 d = t*( ak*akp1-cone )
253 a( k, k ) = akp1 / d
254 a( k+1, k+1 ) = ak / d
255 a( k, k+1 ) = -akkp1 / d
256
257
258
259 IF( k.GT.1 ) THEN
260 CALL ccopy( k-1, a( 1, k ), 1, work, 1 )
261 CALL csymv( uplo, k-1, -cone, a, lda, work, 1, czero,
262 $ a( 1, k ), 1 )
263 a( k, k ) = a( k, k ) -
cdotu( k-1, work, 1, a( 1,
264 $ k ),
265 $ 1 )
266 a( k, k+1 ) = a( k, k+1 ) -
267 $
cdotu( k-1, a( 1, k ), 1, a( 1, k+1 ),
268 $ 1 )
269 CALL ccopy( k-1, a( 1, k+1 ), 1, work, 1 )
270 CALL csymv( uplo, k-1, -cone, a, lda, work, 1, czero,
271 $ a( 1, k+1 ), 1 )
272 a( k+1, k+1 ) = a( k+1, k+1 ) -
273 $
cdotu( k-1, work, 1, a( 1, k+1 ), 1 )
274 END IF
275 kstep = 2
276 END IF
277
278 IF( kstep.EQ.1 ) THEN
279
280
281
282
283 kp = ipiv( k )
284 IF( kp.NE.k ) THEN
285 IF( kp.GT.1 )
286 $
CALL cswap( kp-1, a( 1, k ), 1, a( 1, kp ), 1 )
287 CALL cswap( k-kp-1, a( kp+1, k ), 1, a( kp, kp+1 ),
288 $ lda )
289 temp = a( k, k )
290 a( k, k ) = a( kp, kp )
291 a( kp, kp ) = temp
292 END IF
293 ELSE
294
295
296
297
298 kp = -ipiv( k )
299 IF( kp.NE.k ) THEN
300 IF( kp.GT.1 )
301 $
CALL cswap( kp-1, a( 1, k ), 1, a( 1, kp ), 1 )
302 CALL cswap( k-kp-1, a( kp+1, k ), 1, a( kp, kp+1 ),
303 $ lda )
304
305 temp = a( k, k )
306 a( k, k ) = a( kp, kp )
307 a( kp, kp ) = temp
308 temp = a( k, k+1 )
309 a( k, k+1 ) = a( kp, k+1 )
310 a( kp, k+1 ) = temp
311 END IF
312
313 k = k + 1
314 kp = -ipiv( k )
315 IF( kp.NE.k ) THEN
316 IF( kp.GT.1 )
317 $
CALL cswap( kp-1, a( 1, k ), 1, a( 1, kp ), 1 )
318 CALL cswap( k-kp-1, a( kp+1, k ), 1, a( kp, kp+1 ),
319 $ lda )
320 temp = a( k, k )
321 a( k, k ) = a( kp, kp )
322 a( kp, kp ) = temp
323 END IF
324 END IF
325
326 k = k + 1
327 GO TO 30
328 40 CONTINUE
329
330 ELSE
331
332
333
334
335
336
337 k = n
338 50 CONTINUE
339
340
341
342 IF( k.LT.1 )
343 $ GO TO 60
344
345 IF( ipiv( k ).GT.0 ) THEN
346
347
348
349
350
351 a( k, k ) = cone / a( k, k )
352
353
354
355 IF( k.LT.n ) THEN
356 CALL ccopy( n-k, a( k+1, k ), 1, work, 1 )
357 CALL csymv( uplo, n-k,-cone, a( k+1, k+1 ), lda, work,
358 $ 1,
359 $ czero, a( k+1, k ), 1 )
360 a( k, k ) = a( k, k ) -
cdotu( n-k, work, 1, a( k+1,
361 $ k ),
362 $ 1 )
363 END IF
364 kstep = 1
365 ELSE
366
367
368
369
370
371 t = a( k, k-1 )
372 ak = a( k-1, k-1 ) / t
373 akp1 = a( k, k ) / t
374 akkp1 = a( k, k-1 ) / t
375 d = t*( ak*akp1-cone )
376 a( k-1, k-1 ) = akp1 / d
377 a( k, k ) = ak / d
378 a( k, k-1 ) = -akkp1 / d
379
380
381
382 IF( k.LT.n ) THEN
383 CALL ccopy( n-k, a( k+1, k ), 1, work, 1 )
384 CALL csymv( uplo, n-k,-cone, a( k+1, k+1 ), lda, work,
385 $ 1,
386 $ czero, a( k+1, k ), 1 )
387 a( k, k ) = a( k, k ) -
cdotu( n-k, work, 1, a( k+1,
388 $ k ),
389 $ 1 )
390 a( k, k-1 ) = a( k, k-1 ) -
391 $
cdotu( n-k, a( k+1, k ), 1, a( k+1,
392 $ k-1 ),
393 $ 1 )
394 CALL ccopy( n-k, a( k+1, k-1 ), 1, work, 1 )
395 CALL csymv( uplo, n-k,-cone, a( k+1, k+1 ), lda, work,
396 $ 1,
397 $ czero, a( k+1, k-1 ), 1 )
398 a( k-1, k-1 ) = a( k-1, k-1 ) -
399 $
cdotu( n-k, work, 1, a( k+1, k-1 ),
400 $ 1 )
401 END IF
402 kstep = 2
403 END IF
404
405 IF( kstep.EQ.1 ) THEN
406
407
408
409
410 kp = ipiv( k )
411 IF( kp.NE.k ) THEN
412 IF( kp.LT.n )
413 $
CALL cswap( n-kp, a( kp+1, k ), 1, a( kp+1, kp ),
414 $ 1 )
415 CALL cswap( kp-k-1, a( k+1, k ), 1, a( kp, k+1 ),
416 $ lda )
417 temp = a( k, k )
418 a( k, k ) = a( kp, kp )
419 a( kp, kp ) = temp
420 END IF
421 ELSE
422
423
424
425
426 kp = -ipiv( k )
427 IF( kp.NE.k ) THEN
428 IF( kp.LT.n )
429 $
CALL cswap( n-kp, a( kp+1, k ), 1, a( kp+1, kp ),
430 $ 1 )
431 CALL cswap( kp-k-1, a( k+1, k ), 1, a( kp, k+1 ),
432 $ lda )
433
434 temp = a( k, k )
435 a( k, k ) = a( kp, kp )
436 a( kp, kp ) = temp
437 temp = a( k, k-1 )
438 a( k, k-1 ) = a( kp, k-1 )
439 a( kp, k-1 ) = temp
440 END IF
441
442 k = k - 1
443 kp = -ipiv( k )
444 IF( kp.NE.k ) THEN
445 IF( kp.LT.n )
446 $
CALL cswap( n-kp, a( kp+1, k ), 1, a( kp+1, kp ),
447 $ 1 )
448 CALL cswap( kp-k-1, a( k+1, k ), 1, a( kp, k+1 ),
449 $ lda )
450 temp = a( k, k )
451 a( k, k ) = a( kp, kp )
452 a( kp, kp ) = temp
453 END IF
454 END IF
455
456 k = k - 1
457 GO TO 50
458 60 CONTINUE
459 END IF
460
461 RETURN
462
463
464
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