C....*...1.........2.........3.........4.........5.........6.........7.*.......8 C DAPLUS 1/10/72 C C PURPOSE C COMPUTE THE MOORE-PENROSE G-INVERSE OF A MATRIX - A+ C OBTAIN THE SINGULAR VALUE DECOMPOSITION OF A MATRIX C C USAGE C CALL DAPLUS(A,N,M,AMP,U,S,V,IR,EPS,D1,D2,D3) C C SUBROUTINES CALLED C DSVD C C ARGUMENTS C A - AN N BY M MATRIX STORED COLUMNWISE (STORAGE MODE OF 0) C ELEMENTS OF A ARE REAL*8 C AMP - MOORE-PENROSE G-INVERSE OF A C AN M BY N MATRIX STORED COLUMNWISE (STORAGE MODE OF 0) C ELEMENTS ARE REAL*8 C N - NUMBER OF ROWS IN A (ON OUTPUT THE NO. OF COLS. OF A+) C M - NUMBER OF COLUMNS IN A (ON OUTPUT THE NO. OF ROWS OF A+) C N MUST BE GREATER THAN OR EQUAL TO M C U - AN N BY M MATRIX STORED COLUMNWISE (STORAGE MODE OF 0) C ELEMENTS OF U ARE REAL*8 C S - A DIAGONAL MATRIX STORED AS AN M-VECTOR (STORAGE MODE OF 2) C ELEMENTS OF S ARE REAL*8 C V - AN M BY M MATRIX STORED COLUMNWISE (STORAGE MODE OF 0) C ELEMENTS OF V ARE REAL*8 C IR - COMPUTED RANK OF A C INTEGER C EPS - VALUE USED TO TEST THE SINGULAR VALUES OF A AND DETERMINE C THE RANK OF A. A REASONABLE VALUE IS EPS = 1.D-13 C REAL*8 C D1 - AN M VECTOR USED FOR WORKSPACE. C D2 - AN M VECTOR USED FOR WORKSPACE. C D3 - AN M VECTOR USED FOR WORKSPACE. C ELEMENTS OF D1,D2,D3 ARE REAL*8 C C REMARKS C A = U*S*(V-TRANSPOSE) C (U-TRANSPOSE)*U = (V-TRANSPOSE)*V = V*(V-TRANSPOSE) = I C A+ = V*(S+)*(U-TRANSPOSE) C S+(I) = 1/S(I) IF S(I).GT.0 AND S+(I)=0 OTHERWISE C IF A CAN BE DESTROYED THE FOLLOWING USAGE WILL CONSERVE CORE C CALL DAPLUS(A,N,M,AMP,A,S,V,IR,EPS,D1,D2,D3) C THE MATRIX A WILL CONTAIN U ON RETURN C C REFERENCE C BUSINGER,P.A. AND GOLUB,G.H., SINGULAR VALUE DECOMPOSITION OF A C COMPLEX MATRIX. COMMUNICATIONS OF THE ACM 12: 564-565 (OCT. 1969) C SUBROUTINE DAPLUS(A,N,M,AMP,U,S,V,IR,EPS,D1,D2,D3) IMPLICIT REAL*8 (A-H,O-Z) save REAL*8 A(N,M),AMP(M,N),U(N,M),S(M),V(M,M),D1(M),D2(M),D3(M) CALL Z1DAPLUS(A,N,M,AMP) CALL DSVD(AMP,N,M,N,M,0,M,M,S,U,V,D1,D2,D3) C C RANK DETERMINATION IR=0 TEST=S(1)*EPS DO 10 J=1,M IF(S(J).GT.TEST) IR=IR+1 D1(J)=0.D0 10 IF(S(J).GT.TEST) D1(J)=1.D0/S(J) C CALL Z2DAPLUS(AMP,M,N,V,D1,U,D2) RETURN END SUBROUTINE Z1DAPLUS(A,N,M,AMP) implicit real*8 (a-h,o-z) save REAL*8 A(1),AMP(1) L=M*N DO 10 I=1,L 10 AMP(I)=A(I) RETURN END SUBROUTINE Z2DAPLUS(A,M,N,V,D1,U,D2) implicit real*8 (a-h,o-z) save REAL*8 A(M,N), V(M,M),D1(M), U(N,M), D2(M) DO 30 I=1,M DO 10 K=1,M 10 D2(K)=V(I,K)*D1(K) DO 20 J=1,N A(I,J)=0.D0 DO 20 K=1,M 20 A(I,J)=A(I,J)+D2(K)*U(J,K) 30 CONTINUE RETURN END