3612 IMPLICIT NONE
3613 INTEGER :: NICNTL, NCNTL, NINFO, INFOMUMPS(80)
3614 parameter(nicntl=10, ncntl=10, ninfo=10)
3615 INTEGER :: JOB,M,N,NUM
3616 INTEGER(8), INTENT(IN) :: NE, LIW,LDW, LA
3617 INTEGER(8) :: IP(N+1), IPQ8(N)
3618 INTEGER :: IRN(NE),PERM(M),IW(LIW)
3619 INTEGER :: ICNTL(NICNTL),INFO(NINFO)
3620 REAL :: A()
3621 REAL :: DW(LDW),CNTL(NCNTL)
3622 INTEGER(8), DIMENSION(:), ALLOCATABLE :: IWtemp8
3623 INTEGER :: allocok
3624 INTEGER :: I,J,WARN1,WARN2,WARN4
3625 INTEGER(8) :: K
3626 REAL :: FACT,ZERO,ONE,RINF,RINF2,RINF3
3627 PARAMETER (zero=0.0e+00,one=1.0e+0)
3630 INTRINSIC abs,log
3631 rinf = cntl(2)
3632 rinf2 = huge(rinf2)/real(2*n)
3633 rinf3 = 0.0e0
3634 warn1 = 0
3635 warn2 = 0
3636 warn4 = 0
3637 IF (job.LT.1 .OR. job.GT.6) THEN
3638 info(1) = -1
3639 info(2) = job
3640 IF (icntl(1).GE.0) WRITE(icntl(1),9001) info(1),'JOB',job
3641 GO TO 99
3642 ENDIF
3643 IF (m.LT.1 .OR. m.LT.n) THEN
3644 info(1) = -2
3645 info(2) = m
3646 IF (icntl(1).GE.0) WRITE(icntl(1),9001) info(1),'M',m
3647 GO TO 99
3648 ENDIF
3649 IF (n.LT.1) THEN
3650 info(1) = -2
3651 info(2) = n
3652 IF (icntl(1).GE.0) WRITE(icntl(1),9001) info(1),'N',n
3653 GO TO 99
3654 ENDIF
3655 IF (ne.LT.1) THEN
3656 info(1) = -3
3658 IF (icntl(1).GE.0) WRITE(icntl(1),9001) info(1),'NE',ne
3659 GO TO 99
3660 ENDIF
3661 IF (job.EQ.1) k = int(4*n + m,8)
3662 IF (job.EQ.2) k = int(n + 2*m,8)
3663 IF (job.EQ.3) k = int(8*n + 2*m + ne,8)
3664 IF (job.EQ.4) k = int(n + m,8)
3665 IF (job.EQ.5) k = int(3*n + 2*m,8)
3666 IF (job.EQ.6) k = int(3*n + 2*m + ne,8)
3667 IF (liw.LT.k) THEN
3668 info(1) = -4
3670 IF (icntl(1).GE.0) WRITE(icntl(1),9004) info(1),k
3671 GO TO 99
3672 ENDIF
3673 IF (job.GT.1) THEN
3674 IF (job.EQ.2) k = int( m,8)
3675 IF (job.EQ.3) k = int(1,8)
3676 IF (job.EQ.4) k = int( 2*m,8)
3677 IF (job.EQ.5) k = int(n + 2*m,8)
3678 IF (job.EQ.6) k = int(n + 3*m,8)
3679 IF (ldw .LT. k) THEN
3680 info(1) = -5
3682 IF (icntl(1).GE.0) WRITE(icntl(1),9005) info(1),k
3683 GO TO 99
3684 ENDIF
3685 ENDIF
3686 IF (icntl(5).EQ.0) THEN
3687 DO 3 i = 1,m
3688 iw(i) = 0
3689 3 CONTINUE
3690 DO 6 j = 1,n
3691 DO 4 k = ip(j),ip(j+1)-1_8
3692 i = irn(k)
3693 IF (i.LT.1 .OR. i.GT.m) THEN
3694 info(1) = -6
3695 info(2) = j
3696 IF (icntl(1).GE.0) WRITE(icntl(1),9006) info(1),j,i
3697 GO TO 99
3698 ENDIF
3699 IF (iw(i).EQ.j) THEN
3700 info(1) = -7
3701 info(2) = j
3702 IF (icntl(1).GE.0) WRITE(icntl(1),9007) info(1),j,i
3703 GO TO 99
3704 ELSE
3705 iw(i) = j
3706 ENDIF
3707 4 CONTINUE
3708 6 CONTINUE
3709 ENDIF
3710 IF (icntl(3).GT.0) THEN
3711 IF (icntl(4).EQ.0 .OR. icntl(4).EQ.1) THEN
3712 WRITE(icntl(3),9020) job,m,n,ne
3713 IF (icntl(4).EQ.0) THEN
3714 WRITE(icntl(3),9021) (ip(j),j=1,
min(10,n+1))
3715 WRITE(icntl(3),9022) (irn(k),k=1_8,
min(10_8,ne))
3716 IF (job.GT.1) WRITE(icntl(3),9023)
3717 & (a(k),k=1_8,
min(10_8,ne))
3718 ELSEIF (icntl(4).EQ.1) THEN
3719 WRITE(icntl(3),9021) (ip(j),j=1,n+1)
3720 WRITE(icntl(3),9022) (irn(k),k=1_8,ne)
3721 IF (job.GT.1) WRITE(icntl(3),9023) (a(k),k=1_8,ne)
3722 ENDIF
3723 WRITE(icntl(3),9024) (icntl(j),j=1,nicntl)
3724 WRITE(icntl(3),9025) (cntl(j),j=1,ncntl)
3725 ENDIF
3726 ENDIF
3727 DO 8 i=1,ninfo
3728 info(i) = 0
3729 8 CONTINUE
3730 IF (job.EQ.1) THEN
3731 DO 10 j = 1,n
3732 iw(j) = int(ip(j+1) - ip(j))
3733 10 CONTINUE
3735 & iw(n+1),iw(2*n+1),iw(3*n+1),iw(3*n+m+1))
3736 GO TO 90
3737 ENDIF
3738 IF (job.EQ.2) THEN
3739 dw(1) =
max(zero,cntl(1))
3741 & iw(1),ipq8,iw(n+1),iw(n+m+1),dw,rinf2)
3742 GO TO 90
3743 ENDIF
3744 IF (job.EQ.3) THEN
3745 DO 20 k = 1,ne
3746 iw(k) = irn(k)
3747 20 CONTINUE
3749 fact =
max(zero,cntl(1))
3751 & iw(ne+n+1),iw(ne+2*n+1),iw(ne+3*n+1),iw(ne+4*n+1),
3752 & iw(ne+5*n+1),iw(ne+5*n+m+1),fact,rinf2)
3753 GO TO 90
3754 ENDIF
3755 IF ((job.EQ.4).OR.(job.EQ.5).or.(job.EQ.6)) THEN
3756 ALLOCATE(iwtemp8(m+n+n), stat=allocok)
3757 IF (allocok.GT.0) THEN
3758 infomumps(1) = -7
3759 infomumps(2) = m+n+n
3760 GOTO 90
3761 ENDIF
3762 ENDIF
3763 IF (job.EQ.4) THEN
3764 DO 50 j = 1,n
3765 fact = zero
3766 DO 30 k = ip(j),ip(j+1)-1_8
3767 IF (abs(a(k)).GT.fact) fact = abs(a(k))
3768 30 CONTINUE
3769 IF(fact .GT. rinf3) rinf3 = fact
3770 DO 40 k = ip(j),ip(j+1)-1_8
3771 a(k) = fact - abs(a(k))
3772 40 CONTINUE
3773 50 CONTINUE
3774 dw(1) =
max(zero,cntl(1))
3775 dw(2) = rinf3
3776 iwtemp8(1) = int(job,8)
3778 & iwtemp8(1),iw(1),iwtemp8(n+1),ipq8,iw(n+1),
3779 & iwtemp8(2*n+1),
3780 & dw(1),dw(m+1),rinf2)
3781 DEALLOCATE(iwtemp8)
3782 GO TO 90
3783 ENDIF
3784 IF (job.EQ.5 .or. job.EQ.6) THEN
3785 rinf3=one
3786 IF (job.EQ.5) THEN
3787 DO 75 j = 1,n
3788 fact = zero
3789 DO 60 k = ip(j),ip(j+1)-1_8
3790 IF (a(k).GT.fact) fact = a(k)
3791 60 CONTINUE
3792 dw(2*m+j) = fact
3793 IF (fact.NE.zero) THEN
3794 fact = log(fact)
3795 IF(fact .GT. rinf3) rinf3=fact
3796 DO 70 k = ip(j),ip(j+1)-1_8
3797 IF (a(k).NE.zero) THEN
3798 a(k) = fact - log(a(k))
3799 IF(a(k) .GT. rinf3) rinf3=a(k)
3800 ELSE
3801 a(k) = fact + rinf
3802 ENDIF
3803 70 CONTINUE
3804 ELSE
3805 DO 71 k = ip(j),ip(j+1)-1_8
3806 a(k) = one
3807 71 CONTINUE
3808 ENDIF
3809 75 CONTINUE
3810 ENDIF
3811 IF (job.EQ.6) THEN
3812 DO 175 k = 1,ne
3813 iw(3*n+2*m+k) = irn(k)
3814 175 CONTINUE
3815 DO 61 i = 1,m
3816 dw(2*m+n+i) = zero
3817 61 CONTINUE
3818 DO 63 j = 1,n
3819 DO 62 k = ip(j),ip(j+1)-1_8
3820 i = irn(k)
3821 IF (a(k).GT.dw(2*m+n+i)) THEN
3822 dw(2*m+n+i) = a(k)
3823 ENDIF
3824 62 CONTINUE
3825 63 CONTINUE
3826 DO 64 i = 1,m
3827 IF (dw(2*m+n+i).NE.zero) THEN
3828 dw(2*m+n+i) = 1.0e0/dw(2*m+n+i)
3829 ENDIF
3830 64 CONTINUE
3831 DO 66 j = 1,n
3832 DO 65 k = ip(j),ip(j+1)-1
3833 i = irn(k)
3834 a(k) = dw(2*m+n+i) * a(k)
3835 65 CONTINUE
3836 66 CONTINUE
3838 DO 176 j = 1,n
3839 IF (ip(j).NE.ip(j+1)) THEN
3840 fact = a(ip(j))
3841 ELSE
3842 fact = zero
3843 ENDIF
3844 dw(2*m+j) = fact
3845 IF (fact.NE.zero) THEN
3846 fact = log(fact)
3847 DO 170 k = ip(j),ip(j+1)-1_8
3848 IF (a(k).NE.zero) THEN
3849 a(k) = fact - log(a(k))
3850 IF(a(k) .GT. rinf3) rinf3=a(k)
3851 ELSE
3852 a(k) = fact + rinf
3853 ENDIF
3854 170 CONTINUE
3855 ELSE
3856 DO 171 k = ip(j),ip(j+1)-1_8
3857 a(k) = one
3858 171 CONTINUE
3859 ENDIF
3860 176 CONTINUE
3861 ENDIF
3862 dw(1) =
max(zero,cntl(1))
3863 rinf3 = rinf3+one
3864 dw(2) = rinf3
3865 iwtemp8(1) = int(job,8)
3866 IF (job.EQ.5) THEN
3868 & iwtemp8(1),iw(1),iwtemp8(n+1),ipq8,iw(n+1),
3869 & iwtemp8(2*n+1),
3870 & dw(1),dw(m+1),rinf2)
3871 ENDIF
3872 IF (job.EQ.6) THEN
3874 & iwtemp8(1),iw(1),iwtemp8(n+1),ipq8,iw(n+1),
3875 & iwtemp8(2*n+1),
3876 & dw(1),dw(m+1),rinf2)
3877 ENDIF
3878 IF ((job.EQ.5).or.(job.EQ.6)) THEN
3879 DEALLOCATE(iwtemp8)
3880 ENDIF
3881 IF (job.EQ.6) THEN
3882 DO 79 i = 1,m
3883 IF (dw(2*m+n+i).NE.0.0e0) THEN
3884 dw(i) = dw(i) + log(dw(2*m+n+i))
3885 ENDIF
3886 79 CONTINUE
3887 ENDIF
3888 IF (num.EQ.n) THEN
3889 DO 80 j = 1,n
3890 IF (dw(2*m+j).NE.zero) THEN
3891 dw(m+j) = dw(m+j) - log(dw(2*m+j))
3892 ELSE
3893 dw(m+j) = zero
3894 ENDIF
3895 80 CONTINUE
3896 ENDIF
3897 fact = 0.5e0*log(rinf2)
3898 DO 86 i = 1,m
3899 IF (dw(i).LT.fact) GO TO 86
3900 warn2 = 2
3901 GO TO 90
3902 86 CONTINUE
3903 DO 87 j = 1,n
3904 IF (dw(m+j).LT.fact) GO TO 87
3905 warn2 = 2
3906 GO TO 90
3907 87 CONTINUE
3908 ENDIF
3909 90 IF (infomumps(1).LT.0) RETURN
3910 IF (num.LT.n) warn1 = 1
3911 IF (job.EQ.4 .OR. job.EQ.5 .OR. job.EQ.6) THEN
3912 IF (cntl(1).LT.zero) warn4 = 4
3913 ENDIF
3914 IF (info(1).EQ.0) THEN
3915 info(1) = warn1 + warn2 + warn4
3916 IF (info(1).GT.0 .AND. icntl(2).GT.0) THEN
3917 WRITE(icntl(2),9010) info(1)
3918 IF (warn1.EQ.1) WRITE(icntl(2),9011)
3919 IF (warn2.EQ.2) WRITE(icntl(2),9012)
3920 IF (warn4.EQ.4) WRITE(icntl(2),9014)
3921 ENDIF
3922 ENDIF
3923 IF (icntl(3).GE.0) THEN
3924 IF (icntl(4).EQ.0 .OR. icntl(4).EQ.1) THEN
3925 WRITE(icntl(3),9030) (info(j),j=1,2)
3926 WRITE(icntl(3),9031) num
3927 IF (icntl(4).EQ.0) THEN
3928 WRITE(icntl(3),9032) (perm(j),j=1,
min(10,m))
3929 IF (job.EQ.5 .OR. job.EQ.6) THEN
3930 WRITE(icntl(3),9033) (dw(j),j=1,
min(10,m))
3931 WRITE(icntl(3),9034) (dw(m+j),j=1,
min(10,n))
3932 ENDIF
3933 ELSEIF (icntl(4).EQ.1) THEN
3934 WRITE(icntl(3),9032) (perm(j),j=1,m)
3935 IF (job.EQ.5 .OR. job.EQ.6) THEN
3936 WRITE(icntl(3),9033) (dw(j),j=1,m)
3937 WRITE(icntl(3),9034) (dw(m+j),j=1,n)
3938 ENDIF
3939 ENDIF
3940 ENDIF
3941 ENDIF
3942 99 RETURN
3943 9001 FORMAT (' ****** Error in SMUMPS_MTRANSA. INFO(1) = ',i2,
3944 & ' because ',(a),' = ',i14)
3945 9004 FORMAT (' ****** Error in SMUMPS_MTRANSA. INFO(1) = ',i2/
3946 & ' LIW too small, must be at least ',i14)
3947 9005 FORMAT (' ****** Error in SMUMPS_MTRANSA. INFO(1) = ',i2/
3948 & ' LDW too small, must be at least ',i14)
3949 9006 FORMAT (' ****** Error in SMUMPS_MTRANSA. INFO(1) = ',i2/
3950 & ' Column ',i8,
3951 & ' contains an entry with invalid row index ',i8)
3952 9007 FORMAT (' ****** Error in SMUMPS_MTRANSA. INFO(1) = ',i2/
3953 & ' Column ',i8,
3954 & ' contains two or more entries with row index ',i8)
3955 9010 FORMAT (' ****** Warning from SMUMPS_MTRANSA. INFO(1) = ',i2)
3956 9011 FORMAT (' - The matrix is structurally singular.')
3957 9012 FORMAT (' - Some scaling factors may be too large.')
3958 9014 FORMAT (' - CNTL(1) is negative and was treated as zero.')
3959 9020 FORMAT (' ****** Input parameters for SMUMPS_MTRANSA:'/
3960 & ' JOB =',i10/' M =',i10/' N =',i10/' NE =',i14)
3961 9021 FORMAT (' IP(1:N+1) = ',8i8/(15x,8i8))
3962 9022 FORMAT (' IRN(1:NE) = ',8i8/(15x,8i8))
3963 9023 FORMAT (' A(1:NE) = ',4(1pd14.4)/(15x,4(1pd14.4)))
3964 9024 FORMAT (' ICNTL(1:10) = ',8i8/(15x,2i8))
3965 9025 FORMAT (' CNTL(1:10) = ',4(1pd14.4)/(15x,4(1pd14.4)))
3966 9030 FORMAT (' ****** Output parameters for SMUMPS_MTRANSA:'/
3967 & ' INFO(1:2) = ',2i8)
3968 9031 FORMAT (' NUM = ',i8)
3969 9032 FORMAT (' PERM(1:M) = ',8i8/(15x,8i8))
3970 9033 FORMAT (' DW(1:M) = ',5(f11.3)/(15x,5(f11.3)))
3971 9034 FORMAT (' DW(M+1:M+N) = ',5(f11.3)/(15x,5(f11.3)))
subroutine smumps_mtranss(m, n, ne, ip, irn, a, iperm, numx, w, len, lenl, lenh, fc, iw, iw4, rlx, rinf)
subroutine smumps_mtransb(m, n, ne, ip, irn, a, iperm, num, jperm, pr, q, l, d, rinf)
subroutine smumps_mtransw(m, n, ne, ip, irn, a, iperm, num, jperm, l32, out, pr, q, l, u, d, rinf)
subroutine smumps_mtransr(n, ne, ip, irn, a)
subroutine smumps_mtransz(m, n, irn, lirn, ip, lenc, iperm, num, pr, arp, cv, out)