C.hr DGMFAC
C@
C....*...1.........2.........3.........4.........5.........6.........7.*
C     DGMFAC      1/16/89 (Drew's twelfth birthday)
C
C     PURPOSE
C     FACTOR A SYMMETRIC, POSITIVE DEFINITE MATRIX AS A = RR' AND FACTOR
C     ITS INVERSE AS INV(A)=P'P WHERE R AND P ARE UPPER TRIANGULAR
C
C     USAGE
C     CALL DGMFAC(A,M,R,P,EPS,IER)
C
C     SUBROUTINES CALLED
C     DMFSD, DRINV
C
C     ARGUMENTS
C     A   - AN M BY M SYMMETRIC, POSITIVE DEFINITE MATRIX STORED
C           COLUMNWISE (STORAGE MODE 0).
C           INPUT, REAL*8
C     R   - FACTOR OF A, A=RR', AN M BY M MATRIX STORED COLUMNWISE
C           (STORAGE MODE 0).
C           OUTPUT, REAL*8
C     P   - FACTOR OF A INVERSE, INV(A)=P'P, AN M BY M MATRIX STORED
C           COLUMNWISE (STORAGE MODE 0).
C           OUTPUT, REAL*8
C     M   - THE NUMBER OF ROWS (COLUMNS) IN A.
C           INPUT, INTEGER*4
C     EPS - CONSTANT BETWEEN ZERO AND ONE WHICH IS USED AS RELATIVE
C           TOLERANCE FOR TEST ON LOSS OF SIGNIFICANCE, A REASONABLE
C           VALUE IS 1.D-13.
C           INPUT, REAL*8
C     IER - OUTPUT ERROR PARAMETER, CODED AS FOLLOWS:
C           IER=0  - NO ERROR.
C           IER=-1 - NO RESULT BECAUSE OF WRONG INPUT PARAMETER M,EPS OR
C                    BECAUSE SOME RADICAND IS NOT POSITIVE (MATRIX A IS
C                    NOT POSITIVE DEFINITE, POSSIBLY DUE TO LOSS OF
C                    SIGNIFICANCE).
C           IER=J  - WARNING WHICH INDICATES LOSS OF SIGNIFICANCE.  THE
C                    RADICAND FORMED AT FACTORIZATION STEP J+1 WAS STILL
C                    POSITIVE BUT NO LONGER GREATER THAN
C                    DABS(EPS*A(J*(J+1)/2)).
C
      SUBROUTINE DGMFAC(A,M,R,P,EPS,IER)
      IMPLICIT REAL*8 (A-H,O-Z)
      save
      REAL*8 A(M*M),R(M*M),P(M*M)
C
C     PERMUTE THE ROWS AND COLUMNS OF A AND STORE IN P IN STORAGE MODE 1
C     THE PERMUTAIONS ARE BECAUSE WE FACTOR AS UPPER TRAINGULAR INSTEAD
C     OF THE STANDARD LOWER TRIANGULAR CHOLESKY FACTORIZATION.
C
      DO 10 J=1,M
      JJ=M+1-J
      DO 10 I=J,M
      II=M+1-I
10    P(JJ*(JJ-1)/2+II)=A(M*(J-1)+I)
C
C     COMPUTE THE CHOLESKY FACTORIZATION
C
      CALL DMFSD(P,M,EPS,IER)
      IF (IER.LT.0) RETURN
C
C     UNDO THE PERMUTATIONS AND PUT THE FACTOR IN R IN STORAGE MODE 1
C
      DO 20 J=1,M
      JJ=M+1-J
      DO 20 I=1,J
      II=M+1-I
20    R(J*(J-1)/2+I)=P(II*(II-1)/2+JJ)
C
C     COPY R TO P AND INVERT P
C
      DO 30 I=1,M*(M+1)/2
30    P(I)=R(I)
      CALL DRINV(P,M)
C
C     R AND P ARE IN COMPRESSED FORM, STORAGE MODE 1.  EXPAND TO
C     STORAGE MODE 0
C
      DO 40 JJ=1,M
      J=M+1-JJ
      DO 40 II=JJ,M
      I=M+1-II
      R(M*(J-1)+I)=R(J*(J-1)/2+I)
40    P(M*(J-1)+I)=P(J*(J-1)/2+I)
C
      DO 50 J=1,M
      DO 50 I=J,M
      IF(I.NE.J) THEN
         R(M*(J-1)+I)=0.D0
         P(M*(J-1)+I)=0.D0
         ENDIF
50    CONTINUE
C
      RETURN
      END
