229
230
231
232
233
234
235 CHARACTER DIAG, NORMIN, TRANS, UPLO
236 INTEGER INFO, N
237 DOUBLE PRECISION SCALE
238
239
240 DOUBLE PRECISION CNORM( * )
241 COMPLEX*16 AP( * ), X( * )
242
243
244
245
246
247 DOUBLE PRECISION ZERO, HALF, ONE, TWO
248 parameter( zero = 0.0d+0, half = 0.5d+0, one = 1.0d+0,
249 $ two = 2.0d+0 )
250
251
252 LOGICAL NOTRAN, NOUNIT, UPPER
253 INTEGER I, IMAX, IP, J, JFIRST, JINC, JLAST, JLEN
254 DOUBLE PRECISION BIGNUM, GROW, REC, SMLNUM, TJJ, TMAX, TSCAL,
255 $ XBND, XJ, XMAX
256 COMPLEX*16 CSUMJ, TJJS, USCAL, ZDUM
257
258
259 LOGICAL LSAME
260 INTEGER IDAMAX, IZAMAX
261 DOUBLE PRECISION DLAMCH, DZASUM
262 COMPLEX*16 ZDOTC, ZDOTU, ZLADIV
266
267
269
270
271 INTRINSIC abs, dble, dcmplx, dconjg, dimag, max, min
272
273
274 DOUBLE PRECISION CABS1, CABS2
275
276
277 cabs1( zdum ) = abs( dble( zdum ) ) + abs( dimag( zdum ) )
278 cabs2( zdum ) = abs( dble( zdum ) / 2.d0 ) +
279 $ abs( dimag( zdum ) / 2.d0 )
280
281
282
283 info = 0
284 upper =
lsame( uplo,
'U' )
285 notran =
lsame( trans,
'N' )
286 nounit =
lsame( diag,
'N' )
287
288
289
290 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
291 info = -1
292 ELSE IF( .NOT.notran .AND. .NOT.
lsame( trans,
'T' ) .AND. .NOT.
293 $
lsame( trans,
'C' ) )
THEN
294 info = -2
295 ELSE IF( .NOT.nounit .AND. .NOT.
lsame( diag,
'U' ) )
THEN
296 info = -3
297 ELSE IF( .NOT.
lsame( normin,
'Y' ) .AND. .NOT.
298 $
lsame( normin,
'N' ) )
THEN
299 info = -4
300 ELSE IF( n.LT.0 ) THEN
301 info = -5
302 END IF
303 IF( info.NE.0 ) THEN
304 CALL xerbla(
'ZLATPS', -info )
305 RETURN
306 END IF
307
308
309
310 IF( n.EQ.0 )
311 $ RETURN
312
313
314
315 smlnum =
dlamch(
'Safe minimum' )
316 bignum = one / smlnum
317 smlnum = smlnum /
dlamch(
'Precision' )
318 bignum = one / smlnum
319 scale = one
320
321 IF(
lsame( normin,
'N' ) )
THEN
322
323
324
325 IF( upper ) THEN
326
327
328
329 ip = 1
330 DO 10 j = 1, n
331 cnorm( j ) =
dzasum( j-1, ap( ip ), 1 )
332 ip = ip + j
333 10 CONTINUE
334 ELSE
335
336
337
338 ip = 1
339 DO 20 j = 1, n - 1
340 cnorm( j ) =
dzasum( n-j, ap( ip+1 ), 1 )
341 ip = ip + n - j + 1
342 20 CONTINUE
343 cnorm( n ) = zero
344 END IF
345 END IF
346
347
348
349
350 imax =
idamax( n, cnorm, 1 )
351 tmax = cnorm( imax )
352 IF( tmax.LE.bignum*half ) THEN
353 tscal = one
354 ELSE
355 tscal = half / ( smlnum*tmax )
356 CALL dscal( n, tscal, cnorm, 1 )
357 END IF
358
359
360
361
362 xmax = zero
363 DO 30 j = 1, n
364 xmax = max( xmax, cabs2( x( j ) ) )
365 30 CONTINUE
366 xbnd = xmax
367 IF( notran ) THEN
368
369
370
371 IF( upper ) THEN
372 jfirst = n
373 jlast = 1
374 jinc = -1
375 ELSE
376 jfirst = 1
377 jlast = n
378 jinc = 1
379 END IF
380
381 IF( tscal.NE.one ) THEN
382 grow = zero
383 GO TO 60
384 END IF
385
386 IF( nounit ) THEN
387
388
389
390
391
392
393 grow = half / max( xbnd, smlnum )
394 xbnd = grow
395 ip = jfirst*( jfirst+1 ) / 2
396 jlen = n
397 DO 40 j = jfirst, jlast, jinc
398
399
400
401 IF( grow.LE.smlnum )
402 $ GO TO 60
403
404 tjjs = ap( ip )
405 tjj = cabs1( tjjs )
406
407 IF( tjj.GE.smlnum ) THEN
408
409
410
411 xbnd = min( xbnd, min( one, tjj )*grow )
412 ELSE
413
414
415
416 xbnd = zero
417 END IF
418
419 IF( tjj+cnorm( j ).GE.smlnum ) THEN
420
421
422
423 grow = grow*( tjj / ( tjj+cnorm( j ) ) )
424 ELSE
425
426
427
428 grow = zero
429 END IF
430 ip = ip + jinc*jlen
431 jlen = jlen - 1
432 40 CONTINUE
433 grow = xbnd
434 ELSE
435
436
437
438
439
440 grow = min( one, half / max( xbnd, smlnum ) )
441 DO 50 j = jfirst, jlast, jinc
442
443
444
445 IF( grow.LE.smlnum )
446 $ GO TO 60
447
448
449
450 grow = grow*( one / ( one+cnorm( j ) ) )
451 50 CONTINUE
452 END IF
453 60 CONTINUE
454
455 ELSE
456
457
458
459 IF( upper ) THEN
460 jfirst = 1
461 jlast = n
462 jinc = 1
463 ELSE
464 jfirst = n
465 jlast = 1
466 jinc = -1
467 END IF
468
469 IF( tscal.NE.one ) THEN
470 grow = zero
471 GO TO 90
472 END IF
473
474 IF( nounit ) THEN
475
476
477
478
479
480
481 grow = half / max( xbnd, smlnum )
482 xbnd = grow
483 ip = jfirst*( jfirst+1 ) / 2
484 jlen = 1
485 DO 70 j = jfirst, jlast, jinc
486
487
488
489 IF( grow.LE.smlnum )
490 $ GO TO 90
491
492
493
494 xj = one + cnorm( j )
495 grow = min( grow, xbnd / xj )
496
497 tjjs = ap( ip )
498 tjj = cabs1( tjjs )
499
500 IF( tjj.GE.smlnum ) THEN
501
502
503
504 IF( xj.GT.tjj )
505 $ xbnd = xbnd*( tjj / xj )
506 ELSE
507
508
509
510 xbnd = zero
511 END IF
512 jlen = jlen + 1
513 ip = ip + jinc*jlen
514 70 CONTINUE
515 grow = min( grow, xbnd )
516 ELSE
517
518
519
520
521
522 grow = min( one, half / max( xbnd, smlnum ) )
523 DO 80 j = jfirst, jlast, jinc
524
525
526
527 IF( grow.LE.smlnum )
528 $ GO TO 90
529
530
531
532 xj = one + cnorm( j )
533 grow = grow / xj
534 80 CONTINUE
535 END IF
536 90 CONTINUE
537 END IF
538
539 IF( ( grow*tscal ).GT.smlnum ) THEN
540
541
542
543
544 CALL ztpsv( uplo, trans, diag, n, ap, x, 1 )
545 ELSE
546
547
548
549 IF( xmax.GT.bignum*half ) THEN
550
551
552
553
554 scale = ( bignum*half ) / xmax
555 CALL zdscal( n, scale, x, 1 )
556 xmax = bignum
557 ELSE
558 xmax = xmax*two
559 END IF
560
561 IF( notran ) THEN
562
563
564
565 ip = jfirst*( jfirst+1 ) / 2
566 DO 120 j = jfirst, jlast, jinc
567
568
569
570 xj = cabs1( x( j ) )
571 IF( nounit ) THEN
572 tjjs = ap( ip )*tscal
573 ELSE
574 tjjs = tscal
575 IF( tscal.EQ.one )
576 $ GO TO 110
577 END IF
578 tjj = cabs1( tjjs )
579 IF( tjj.GT.smlnum ) THEN
580
581
582
583 IF( tjj.LT.one ) THEN
584 IF( xj.GT.tjj*bignum ) THEN
585
586
587
588 rec = one / xj
589 CALL zdscal( n, rec, x, 1 )
590 scale = scale*rec
591 xmax = xmax*rec
592 END IF
593 END IF
594 x( j ) =
zladiv( x( j ), tjjs )
595 xj = cabs1( x( j ) )
596 ELSE IF( tjj.GT.zero ) THEN
597
598
599
600 IF( xj.GT.tjj*bignum ) THEN
601
602
603
604
605 rec = ( tjj*bignum ) / xj
606 IF( cnorm( j ).GT.one ) THEN
607
608
609
610
611 rec = rec / cnorm( j )
612 END IF
613 CALL zdscal( n, rec, x, 1 )
614 scale = scale*rec
615 xmax = xmax*rec
616 END IF
617 x( j ) =
zladiv( x( j ), tjjs )
618 xj = cabs1( x( j ) )
619 ELSE
620
621
622
623
624 DO 100 i = 1, n
625 x( i ) = zero
626 100 CONTINUE
627 x( j ) = one
628 xj = one
629 scale = zero
630 xmax = zero
631 END IF
632 110 CONTINUE
633
634
635
636
637 IF( xj.GT.one ) THEN
638 rec = one / xj
639 IF( cnorm( j ).GT.( bignum-xmax )*rec ) THEN
640
641
642
643 rec = rec*half
644 CALL zdscal( n, rec, x, 1 )
645 scale = scale*rec
646 END IF
647 ELSE IF( xj*cnorm( j ).GT.( bignum-xmax ) ) THEN
648
649
650
651 CALL zdscal( n, half, x, 1 )
652 scale = scale*half
653 END IF
654
655 IF( upper ) THEN
656 IF( j.GT.1 ) THEN
657
658
659
660
661 CALL zaxpy( j-1, -x( j )*tscal, ap( ip-j+1 ), 1,
662 $ x,
663 $ 1 )
665 xmax = cabs1( x( i ) )
666 END IF
667 ip = ip - j
668 ELSE
669 IF( j.LT.n ) THEN
670
671
672
673
674 CALL zaxpy( n-j, -x( j )*tscal, ap( ip+1 ), 1,
675 $ x( j+1 ), 1 )
676 i = j +
izamax( n-j, x( j+1 ), 1 )
677 xmax = cabs1( x( i ) )
678 END IF
679 ip = ip + n - j + 1
680 END IF
681 120 CONTINUE
682
683 ELSE IF(
lsame( trans,
'T' ) )
THEN
684
685
686
687 ip = jfirst*( jfirst+1 ) / 2
688 jlen = 1
689 DO 170 j = jfirst, jlast, jinc
690
691
692
693
694 xj = cabs1( x( j ) )
695 uscal = tscal
696 rec = one / max( xmax, one )
697 IF( cnorm( j ).GT.( bignum-xj )*rec ) THEN
698
699
700
701 rec = rec*half
702 IF( nounit ) THEN
703 tjjs = ap( ip )*tscal
704 ELSE
705 tjjs = tscal
706 END IF
707 tjj = cabs1( tjjs )
708 IF( tjj.GT.one ) THEN
709
710
711
712 rec = min( one, rec*tjj )
713 uscal =
zladiv( uscal, tjjs )
714 END IF
715 IF( rec.LT.one ) THEN
716 CALL zdscal( n, rec, x, 1 )
717 scale = scale*rec
718 xmax = xmax*rec
719 END IF
720 END IF
721
722 csumj = zero
723 IF( uscal.EQ.dcmplx( one ) ) THEN
724
725
726
727
728 IF( upper ) THEN
729 csumj =
zdotu( j-1, ap( ip-j+1 ), 1, x, 1 )
730 ELSE IF( j.LT.n ) THEN
731 csumj =
zdotu( n-j, ap( ip+1 ), 1, x( j+1 ), 1 )
732 END IF
733 ELSE
734
735
736
737 IF( upper ) THEN
738 DO 130 i = 1, j - 1
739 csumj = csumj + ( ap( ip-j+i )*uscal )*x( i )
740 130 CONTINUE
741 ELSE IF( j.LT.n ) THEN
742 DO 140 i = 1, n - j
743 csumj = csumj + ( ap( ip+i )*uscal )*x( j+i )
744 140 CONTINUE
745 END IF
746 END IF
747
748 IF( uscal.EQ.dcmplx( tscal ) ) THEN
749
750
751
752
753 x( j ) = x( j ) - csumj
754 xj = cabs1( x( j ) )
755 IF( nounit ) THEN
756
757
758
759 tjjs = ap( ip )*tscal
760 ELSE
761 tjjs = tscal
762 IF( tscal.EQ.one )
763 $ GO TO 160
764 END IF
765 tjj = cabs1( tjjs )
766 IF( tjj.GT.smlnum ) THEN
767
768
769
770 IF( tjj.LT.one ) THEN
771 IF( xj.GT.tjj*bignum ) THEN
772
773
774
775 rec = one / xj
776 CALL zdscal( n, rec, x, 1 )
777 scale = scale*rec
778 xmax = xmax*rec
779 END IF
780 END IF
781 x( j ) =
zladiv( x( j ), tjjs )
782 ELSE IF( tjj.GT.zero ) THEN
783
784
785
786 IF( xj.GT.tjj*bignum ) THEN
787
788
789
790 rec = ( tjj*bignum ) / xj
791 CALL zdscal( n, rec, x, 1 )
792 scale = scale*rec
793 xmax = xmax*rec
794 END IF
795 x( j ) =
zladiv( x( j ), tjjs )
796 ELSE
797
798
799
800
801 DO 150 i = 1, n
802 x( i ) = zero
803 150 CONTINUE
804 x( j ) = one
805 scale = zero
806 xmax = zero
807 END IF
808 160 CONTINUE
809 ELSE
810
811
812
813
814 x( j ) =
zladiv( x( j ), tjjs ) - csumj
815 END IF
816 xmax = max( xmax, cabs1( x( j ) ) )
817 jlen = jlen + 1
818 ip = ip + jinc*jlen
819 170 CONTINUE
820
821 ELSE
822
823
824
825 ip = jfirst*( jfirst+1 ) / 2
826 jlen = 1
827 DO 220 j = jfirst, jlast, jinc
828
829
830
831
832 xj = cabs1( x( j ) )
833 uscal = tscal
834 rec = one / max( xmax, one )
835 IF( cnorm( j ).GT.( bignum-xj )*rec ) THEN
836
837
838
839 rec = rec*half
840 IF( nounit ) THEN
841 tjjs = dconjg( ap( ip ) )*tscal
842 ELSE
843 tjjs = tscal
844 END IF
845 tjj = cabs1( tjjs )
846 IF( tjj.GT.one ) THEN
847
848
849
850 rec = min( one, rec*tjj )
851 uscal =
zladiv( uscal, tjjs )
852 END IF
853 IF( rec.LT.one ) THEN
854 CALL zdscal( n, rec, x, 1 )
855 scale = scale*rec
856 xmax = xmax*rec
857 END IF
858 END IF
859
860 csumj = zero
861 IF( uscal.EQ.dcmplx( one ) ) THEN
862
863
864
865
866 IF( upper ) THEN
867 csumj =
zdotc( j-1, ap( ip-j+1 ), 1, x, 1 )
868 ELSE IF( j.LT.n ) THEN
869 csumj =
zdotc( n-j, ap( ip+1 ), 1, x( j+1 ), 1 )
870 END IF
871 ELSE
872
873
874
875 IF( upper ) THEN
876 DO 180 i = 1, j - 1
877 csumj = csumj + ( dconjg( ap( ip-j+i ) )*uscal )
878 $ *x( i )
879 180 CONTINUE
880 ELSE IF( j.LT.n ) THEN
881 DO 190 i = 1, n - j
882 csumj = csumj + ( dconjg( ap( ip+i ) )*uscal )*
883 $ x( j+i )
884 190 CONTINUE
885 END IF
886 END IF
887
888 IF( uscal.EQ.dcmplx( tscal ) ) THEN
889
890
891
892
893 x( j ) = x( j ) - csumj
894 xj = cabs1( x( j ) )
895 IF( nounit ) THEN
896
897
898
899 tjjs = dconjg( ap( ip ) )*tscal
900 ELSE
901 tjjs = tscal
902 IF( tscal.EQ.one )
903 $ GO TO 210
904 END IF
905 tjj = cabs1( tjjs )
906 IF( tjj.GT.smlnum ) THEN
907
908
909
910 IF( tjj.LT.one ) THEN
911 IF( xj.GT.tjj*bignum ) THEN
912
913
914
915 rec = one / xj
916 CALL zdscal( n, rec, x, 1 )
917 scale = scale*rec
918 xmax = xmax*rec
919 END IF
920 END IF
921 x( j ) =
zladiv( x( j ), tjjs )
922 ELSE IF( tjj.GT.zero ) THEN
923
924
925
926 IF( xj.GT.tjj*bignum ) THEN
927
928
929
930 rec = ( tjj*bignum ) / xj
931 CALL zdscal( n, rec, x, 1 )
932 scale = scale*rec
933 xmax = xmax*rec
934 END IF
935 x( j ) =
zladiv( x( j ), tjjs )
936 ELSE
937
938
939
940
941 DO 200 i = 1, n
942 x( i ) = zero
943 200 CONTINUE
944 x( j ) = one
945 scale = zero
946 xmax = zero
947 END IF
948 210 CONTINUE
949 ELSE
950
951
952
953
954 x( j ) =
zladiv( x( j ), tjjs ) - csumj
955 END IF
956 xmax = max( xmax, cabs1( x( j ) ) )
957 jlen = jlen + 1
958 ip = ip + jinc*jlen
959 220 CONTINUE
960 END IF
961 scale = scale / tscal
962 END IF
963
964
965
966 IF( tscal.NE.one ) THEN
967 CALL dscal( n, one / tscal, cnorm, 1 )
968 END IF
969
970 RETURN
971
972
973
subroutine xerbla(srname, info)
double precision function dzasum(n, zx, incx)
DZASUM
subroutine zaxpy(n, za, zx, incx, zy, incy)
ZAXPY
complex *16 function zdotc(n, zx, incx, zy, incy)
ZDOTC
complex *16 function zdotu(n, zx, incx, zy, incy)
ZDOTU
integer function idamax(n, dx, incx)
IDAMAX
integer function izamax(n, zx, incx)
IZAMAX
complex *16 function zladiv(x, y)
ZLADIV performs complex division in real arithmetic, avoiding unnecessary overflow.
double precision function dlamch(cmach)
DLAMCH
logical function lsame(ca, cb)
LSAME
subroutine dscal(n, da, dx, incx)
DSCAL
subroutine zdscal(n, da, zx, incx)
ZDSCAL
subroutine ztpsv(uplo, trans, diag, n, ap, x, incx)
ZTPSV