157
158
159
160
161
162
163 CHARACTER UPLO
164 INTEGER INFO, N
165
166
167 INTEGER IPIV( * )
168 COMPLEX*16 AP( * )
169
170
171
172
173
174 DOUBLE PRECISION ZERO, ONE
175 parameter( zero = 0.0d+0, one = 1.0d+0 )
176 DOUBLE PRECISION EIGHT, SEVTEN
177 parameter( eight = 8.0d+0, sevten = 17.0d+0 )
178
179
180 LOGICAL UPPER
181 INTEGER I, IMAX, J, JMAX, K, KC, KK, KNC, KP, KPC,
182 $ KSTEP, KX, NPP
183 DOUBLE PRECISION ABSAKK, ALPHA, COLMAX, D, D11, D22, R1, ROWMAX,
184 $ TT
185 COMPLEX*16 D12, D21, T, WK, WKM1, WKP1, ZDUM
186
187
188 LOGICAL LSAME
189 INTEGER IZAMAX
190 DOUBLE PRECISION DLAPY2
192
193
195
196
197 INTRINSIC abs, dble, dcmplx, dconjg, dimag, max, sqrt
198
199
200 DOUBLE PRECISION CABS1
201
202
203 cabs1( zdum ) = abs( dble( zdum ) ) + abs( dimag( zdum ) )
204
205
206
207
208
209 info = 0
210 upper =
lsame( uplo,
'U' )
211 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
212 info = -1
213 ELSE IF( n.LT.0 ) THEN
214 info = -2
215 END IF
216 IF( info.NE.0 ) THEN
217 CALL xerbla(
'ZHPTRF', -info )
218 RETURN
219 END IF
220
221
222
223 alpha = ( one+sqrt( sevten ) ) / eight
224
225 IF( upper ) THEN
226
227
228
229
230
231
232 k = n
233 kc = ( n-1 )*n / 2 + 1
234 10 CONTINUE
235 knc = kc
236
237
238
239 IF( k.LT.1 )
240 $ GO TO 110
241 kstep = 1
242
243
244
245
246 absakk = abs( dble( ap( kc+k-1 ) ) )
247
248
249
250
251 IF( k.GT.1 ) THEN
252 imax =
izamax( k-1, ap( kc ), 1 )
253 colmax = cabs1( ap( kc+imax-1 ) )
254 ELSE
255 colmax = zero
256 END IF
257
258 IF( max( absakk, colmax ).EQ.zero ) THEN
259
260
261
262 IF( info.EQ.0 )
263 $ info = k
264 kp = k
265 ap( kc+k-1 ) = dble( ap( kc+k-1 ) )
266 ELSE
267 IF( absakk.GE.alpha*colmax ) THEN
268
269
270
271 kp = k
272 ELSE
273
274
275
276
277 rowmax = zero
278 jmax = imax
279 kx = imax*( imax+1 ) / 2 + imax
280 DO 20 j = imax + 1, k
281 IF( cabs1( ap( kx ) ).GT.rowmax ) THEN
282 rowmax = cabs1( ap( kx ) )
283 jmax = j
284 END IF
285 kx = kx + j
286 20 CONTINUE
287 kpc = ( imax-1 )*imax / 2 + 1
288 IF( imax.GT.1 ) THEN
289 jmax =
izamax( imax-1, ap( kpc ), 1 )
290 rowmax = max( rowmax, cabs1( ap( kpc+jmax-1 ) ) )
291 END IF
292
293 IF( absakk.GE.alpha*colmax*( colmax / rowmax ) ) THEN
294
295
296
297 kp = k
298 ELSE IF( abs( dble( ap( kpc+imax-1 ) ) ).GE.alpha*
299 $ rowmax ) THEN
300
301
302
303
304 kp = imax
305 ELSE
306
307
308
309
310 kp = imax
311 kstep = 2
312 END IF
313 END IF
314
315 kk = k - kstep + 1
316 IF( kstep.EQ.2 )
317 $ knc = knc - k + 1
318 IF( kp.NE.kk ) THEN
319
320
321
322
323 CALL zswap( kp-1, ap( knc ), 1, ap( kpc ), 1 )
324 kx = kpc + kp - 1
325 DO 30 j = kp + 1, kk - 1
326 kx = kx + j - 1
327 t = dconjg( ap( knc+j-1 ) )
328 ap( knc+j-1 ) = dconjg( ap( kx ) )
329 ap( kx ) = t
330 30 CONTINUE
331 ap( kx+kk-1 ) = dconjg( ap( kx+kk-1 ) )
332 r1 = dble( ap( knc+kk-1 ) )
333 ap( knc+kk-1 ) = dble( ap( kpc+kp-1 ) )
334 ap( kpc+kp-1 ) = r1
335 IF( kstep.EQ.2 ) THEN
336 ap( kc+k-1 ) = dble( ap( kc+k-1 ) )
337 t = ap( kc+k-2 )
338 ap( kc+k-2 ) = ap( kc+kp-1 )
339 ap( kc+kp-1 ) = t
340 END IF
341 ELSE
342 ap( kc+k-1 ) = dble( ap( kc+k-1 ) )
343 IF( kstep.EQ.2 )
344 $ ap( kc-1 ) = dble( ap( kc-1 ) )
345 END IF
346
347
348
349 IF( kstep.EQ.1 ) THEN
350
351
352
353
354
355
356
357
358
359
360
361 r1 = one / dble( ap( kc+k-1 ) )
362 CALL zhpr( uplo, k-1, -r1, ap( kc ), 1, ap )
363
364
365
366 CALL zdscal( k-1, r1, ap( kc ), 1 )
367 ELSE
368
369
370
371
372
373
374
375
376
377
378
379
380
381 IF( k.GT.2 ) THEN
382
383 d =
dlapy2( dble( ap( k-1+( k-1 )*k / 2 ) ),
384 $ dimag( ap( k-1+( k-1 )*k / 2 ) ) )
385 d22 = dble( ap( k-1+( k-2 )*( k-1 ) / 2 ) ) / d
386 d11 = dble( ap( k+( k-1 )*k / 2 ) ) / d
387 tt = one / ( d11*d22-one )
388 d12 = ap( k-1+( k-1 )*k / 2 ) / d
389 d = tt / d
390
391 DO 50 j = k - 2, 1, -1
392 wkm1 = d*( d11*ap( j+( k-2 )*( k-1 ) / 2 )-
393 $ dconjg( d12 )*ap( j+( k-1 )*k / 2 ) )
394 wk = d*( d22*ap( j+( k-1 )*k / 2 )-d12*
395 $ ap( j+( k-2 )*( k-1 ) / 2 ) )
396 DO 40 i = j, 1, -1
397 ap( i+( j-1 )*j / 2 ) = ap( i+( j-1 )*j / 2 ) -
398 $ ap( i+( k-1 )*k / 2 )*dconjg( wk ) -
399 $ ap( i+( k-2 )*( k-1 ) / 2 )*dconjg( wkm1 )
400 40 CONTINUE
401 ap( j+( k-1 )*k / 2 ) = wk
402 ap( j+( k-2 )*( k-1 ) / 2 ) = wkm1
403 ap( j+( j-1 )*j / 2 ) = dcmplx( dble( ap( j+( j-
404 $ 1 )*j / 2 ) ), 0.0d+0 )
405 50 CONTINUE
406
407 END IF
408
409 END IF
410 END IF
411
412
413
414 IF( kstep.EQ.1 ) THEN
415 ipiv( k ) = kp
416 ELSE
417 ipiv( k ) = -kp
418 ipiv( k-1 ) = -kp
419 END IF
420
421
422
423 k = k - kstep
424 kc = knc - k
425 GO TO 10
426
427 ELSE
428
429
430
431
432
433
434 k = 1
435 kc = 1
436 npp = n*( n+1 ) / 2
437 60 CONTINUE
438 knc = kc
439
440
441
442 IF( k.GT.n )
443 $ GO TO 110
444 kstep = 1
445
446
447
448
449 absakk = abs( dble( ap( kc ) ) )
450
451
452
453
454 IF( k.LT.n ) THEN
455 imax = k +
izamax( n-k, ap( kc+1 ), 1 )
456 colmax = cabs1( ap( kc+imax-k ) )
457 ELSE
458 colmax = zero
459 END IF
460
461 IF( max( absakk, colmax ).EQ.zero ) THEN
462
463
464
465 IF( info.EQ.0 )
466 $ info = k
467 kp = k
468 ap( kc ) = dble( ap( kc ) )
469 ELSE
470 IF( absakk.GE.alpha*colmax ) THEN
471
472
473
474 kp = k
475 ELSE
476
477
478
479
480 rowmax = zero
481 kx = kc + imax - k
482 DO 70 j = k, imax - 1
483 IF( cabs1( ap( kx ) ).GT.rowmax ) THEN
484 rowmax = cabs1( ap( kx ) )
485 jmax = j
486 END IF
487 kx = kx + n - j
488 70 CONTINUE
489 kpc = npp - ( n-imax+1 )*( n-imax+2 ) / 2 + 1
490 IF( imax.LT.n ) THEN
491 jmax = imax +
izamax( n-imax, ap( kpc+1 ), 1 )
492 rowmax = max( rowmax, cabs1( ap( kpc+jmax-imax ) ) )
493 END IF
494
495 IF( absakk.GE.alpha*colmax*( colmax / rowmax ) ) THEN
496
497
498
499 kp = k
500 ELSE IF( abs( dble( ap( kpc ) ) ).GE.alpha*rowmax ) THEN
501
502
503
504
505 kp = imax
506 ELSE
507
508
509
510
511 kp = imax
512 kstep = 2
513 END IF
514 END IF
515
516 kk = k + kstep - 1
517 IF( kstep.EQ.2 )
518 $ knc = knc + n - k + 1
519 IF( kp.NE.kk ) THEN
520
521
522
523
524 IF( kp.LT.n )
525 $
CALL zswap( n-kp, ap( knc+kp-kk+1 ), 1,
526 $ ap( kpc+1 ),
527 $ 1 )
528 kx = knc + kp - kk
529 DO 80 j = kk + 1, kp - 1
530 kx = kx + n - j + 1
531 t = dconjg( ap( knc+j-kk ) )
532 ap( knc+j-kk ) = dconjg( ap( kx ) )
533 ap( kx ) = t
534 80 CONTINUE
535 ap( knc+kp-kk ) = dconjg( ap( knc+kp-kk ) )
536 r1 = dble( ap( knc ) )
537 ap( knc ) = dble( ap( kpc ) )
538 ap( kpc ) = r1
539 IF( kstep.EQ.2 ) THEN
540 ap( kc ) = dble( ap( kc ) )
541 t = ap( kc+1 )
542 ap( kc+1 ) = ap( kc+kp-k )
543 ap( kc+kp-k ) = t
544 END IF
545 ELSE
546 ap( kc ) = dble( ap( kc ) )
547 IF( kstep.EQ.2 )
548 $ ap( knc ) = dble( ap( knc ) )
549 END IF
550
551
552
553 IF( kstep.EQ.1 ) THEN
554
555
556
557
558
559
560
561 IF( k.LT.n ) THEN
562
563
564
565
566
567 r1 = one / dble( ap( kc ) )
568 CALL zhpr( uplo, n-k, -r1, ap( kc+1 ), 1,
569 $ ap( kc+n-k+1 ) )
570
571
572
573 CALL zdscal( n-k, r1, ap( kc+1 ), 1 )
574 END IF
575 ELSE
576
577
578
579
580
581
582
583
584 IF( k.LT.n-1 ) THEN
585
586
587
588
589
590
591
592
593
595 $ dble( ap( k+1+( k-1 )*( 2*n-k ) / 2 ) ),
596 $ dimag( ap( k+1+( k-1 )*( 2*n-k ) / 2 ) ) )
597 d11 = dble( ap( k+1+k*( 2*n-k-1 ) / 2 ) ) / d
598 d22 = dble( ap( k+( k-1 )*( 2*n-k ) / 2 ) ) / d
599 tt = one / ( d11*d22-one )
600 d21 = ap( k+1+( k-1 )*( 2*n-k ) / 2 ) / d
601 d = tt / d
602
603 DO 100 j = k + 2, n
604 wk = d*( d11*ap( j+( k-1 )*( 2*n-k ) / 2 )-d21*
605 $ ap( j+k*( 2*n-k-1 ) / 2 ) )
606 wkp1 = d*( d22*ap( j+k*( 2*n-k-1 ) / 2 )-
607 $ dconjg( d21 )*ap( j+( k-1 )*( 2*n-k ) /
608 $ 2 ) )
609 DO 90 i = j, n
610 ap( i+( j-1 )*( 2*n-j ) / 2 ) = ap( i+( j-1 )*
611 $ ( 2*n-j ) / 2 ) - ap( i+( k-1 )*( 2*n-k ) /
612 $ 2 )*dconjg( wk ) - ap( i+k*( 2*n-k-1 ) / 2 )*
613 $ dconjg( wkp1 )
614 90 CONTINUE
615 ap( j+( k-1 )*( 2*n-k ) / 2 ) = wk
616 ap( j+k*( 2*n-k-1 ) / 2 ) = wkp1
617 ap( j+( j-1 )*( 2*n-j ) / 2 )
618 $ = dcmplx( dble( ap( j+( j-1 )*( 2*n-j ) / 2 ) ),
619 $ 0.0d+0 )
620 100 CONTINUE
621 END IF
622 END IF
623 END IF
624
625
626
627 IF( kstep.EQ.1 ) THEN
628 ipiv( k ) = kp
629 ELSE
630 ipiv( k ) = -kp
631 ipiv( k+1 ) = -kp
632 END IF
633
634
635
636 k = k + kstep
637 kc = knc + n - k + 2
638 GO TO 60
639
640 END IF
641
642 110 CONTINUE
643 RETURN
644
645
646
subroutine xerbla(srname, info)
subroutine zhpr(uplo, n, alpha, x, incx, ap)
ZHPR
integer function izamax(n, zx, incx)
IZAMAX
double precision function dlapy2(x, y)
DLAPY2 returns sqrt(x2+y2).
logical function lsame(ca, cb)
LSAME
subroutine zdscal(n, da, zx, incx)
ZDSCAL
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP