C....*...1.........2.........3.........4.........5.........6.........7.*.......8
C     DMPINV 8/22/73
C
C     PURPOSE
C     TO COMPUTE THE MOORE-PENROSE INVERSE OF A MATRIX.
C
C     USAGE
C     CALL DMPINV(A,N,M,AMP,IR,W)
C
C     SUBROUTINES CALLED
C     DAPLUS, DSVD, DGMTRA
C
C     ARGUMENTS
C     A   - AN N BY M MATRIX STORED COLUMNWISE (STORAGE MODE 0)
C           ELEMENTS ARE REAL*8
C     N   - NUMBER OF ROWS IN A (NUMBER OF COLUMNS IN AMP)
C           INTEGER
C     M   - NUMBER OF COLUMNS IN A (NUMBER OF ROWS IN AMP)
C           INTEGER
C     AMP - MOORE-PENROSE INVERSE OF A
C           AN M BY N MATRIX STORED COLUMNWISE (STORAGE MODE 0)
C           ELEMENTS ARE REAL*8
C     IR  - COMPUTED RANK OF A
C           INTEGER
C     W   - A WORK VECTOR LENGTH N*M+4*MIN(N,M)+MIN(N,M)**2
C           ELEMENTS ARE REAL*8
C
C     PROGRAMMER
C     DR. THOMAS M. GERIG
C     DEPARTMENT OF STATISTICS
C     NORTH CAROLINA STATE UNIVERSITY
C     RALEIGH, NORTH CAROLINA  27609
C
C
      SUBROUTINE DMPINV(A,N,M,AMP,IR,W)
      IMPLICIT REAL*8(A-H,O-Z)
      save
      REAL*8 A(1),AMP(1),W(1)
      MIN=MIN0(N,M)
      I2=01+N*M
      I3=I2+MIN
      I4=I3+MIN**2
      I5=I4+MIN
      I6=I5+MIN
      IF(N.GE.M) GO TO 10
      CALL DGMTRA(A,W,N,M)
      CALL DAPLUS(W,M,N,A,AMP,W(I2),W(I3),IR,1.D-13,W(I4),W(I5),W(I6))
      CALL DGMTRA(A,AMP,N,M)
      CALL DGMTRA(W,A,M,N)
      RETURN
 10   CALL DAPLUS(A,N,M,AMP,W,W(I2),W(I3),IR,1.D-13,W(I4),W(I5),W(I6))
      RETURN
      END
