127
128
129
130
131
132
133 CHARACTER UPLO
134 INTEGER INFO, LDA, N
135
136
137 INTEGER IPIV( * )
138 COMPLEX*16 A( LDA, * ), WORK( * )
139
140
141
142
143
144 COMPLEX*16 CONE, CZERO
145 parameter( cone = ( 1.0d+0, 0.0d+0 ),
146 $ czero = ( 0.0d+0, 0.0d+0 ) )
147
148
149 LOGICAL UPPER
150 INTEGER K, KP, KSTEP
151 COMPLEX*16 AK, AKKP1, AKP1, D, T, TEMP
152
153
154 LOGICAL LSAME
155 COMPLEX*16 ZDOTU
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(
'ZSYTRI_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 zcopy( k-1, a( 1, k ), 1, work, 1 )
235 CALL zsymv( uplo, k-1, -cone, a, lda, work, 1, czero,
236 $ a( 1, k ), 1 )
237 a( k, k ) = a( k, k ) -
zdotu( 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 zcopy( k-1, a( 1, k ), 1, work, 1 )
261 CALL zsymv( uplo, k-1, -cone, a, lda, work, 1, czero,
262 $ a( 1, k ), 1 )
263 a( k, k ) = a( k, k ) -
zdotu( k-1, work, 1, a( 1,
264 $ k ),
265 $ 1 )
266 a( k, k+1 ) = a( k, k+1 ) -
267 $
zdotu( k-1, a( 1, k ), 1, a( 1, k+1 ),
268 $ 1 )
269 CALL zcopy( k-1, a( 1, k+1 ), 1, work, 1 )
270 CALL zsymv( 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 $
zdotu( 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 zswap( kp-1, a( 1, k ), 1, a( 1, kp ), 1 )
287 CALL zswap( 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 zswap( kp-1, a( 1, k ), 1, a( 1, kp ), 1 )
302 CALL zswap( 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 zswap( kp-1, a( 1, k ), 1, a( 1, kp ), 1 )
318 CALL zswap( 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 zcopy( n-k, a( k+1, k ), 1, work, 1 )
357 CALL zsymv( 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 ) -
zdotu( 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 zcopy( n-k, a( k+1, k ), 1, work, 1 )
384 CALL zsymv( 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 ) -
zdotu( n-k, work, 1, a( k+1,
388 $ k ),
389 $ 1 )
390 a( k, k-1 ) = a( k, k-1 ) -
391 $
zdotu( n-k, a( k+1, k ), 1, a( k+1,
392 $ k-1 ),
393 $ 1 )
394 CALL zcopy( n-k, a( k+1, k-1 ), 1, work, 1 )
395 CALL zsymv( 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 $
zdotu( 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 zswap( n-kp, a( kp+1, k ), 1, a( kp+1, kp ),
414 $ 1 )
415 CALL zswap( 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 zswap( n-kp, a( kp+1, k ), 1, a( kp+1, kp ),
430 $ 1 )
431 CALL zswap( 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 zswap( n-kp, a( kp+1, k ), 1, a( kp+1, kp ),
447 $ 1 )
448 CALL zswap( 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 zcopy(n, zx, incx, zy, incy)
ZCOPY
complex *16 function zdotu(n, zx, incx, zy, incy)
ZDOTU
subroutine zsymv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
ZSYMV computes a matrix-vector product for a complex symmetric matrix.
logical function lsame(ca, cb)
LSAME
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP