C WESTERN MICHIGAN UNIVERSITY C MATRIX.F4 (FILENAME ON LIBRARY DECTAPE) C MATRIX, 2.8.1. (CALLING NAME, SUBLST#) C MATRIX OPERATIONS C MATRIX WAS PROGRAMMED BY SAM ANEMA C LIBRARY DECTAPE PROGRAMS USED: USAGE.MAC C APLIB PROGS. USED: IO, GETFOR, C INTERNAL SUBR: MINVSQ C FORWMU PROGS. USED: DEVCHG, EXISTS, PRINTS C ABOVE COMMENTS AND RIGHT ADJUSTED COMMENTS PUT IN BY WG C DIMENSION SUM(20),IFMT(32) DATA BLANK/' '/ C---------------A(20,20) IS PLACE WHERE USER'S MATRIX IS STORED C--------------- PRIOR TO CALL MINSQV DIMENSION VAR(10),A(20,20) DIMENSION MC(20),MR(20) C---------------X(10,20,20) DETERMINES THE LIMITATION OF TEN C--------------- 20X20 MATRICES. IPT=0 DIMENSION X(10,20,20),NDIM(2,10),RED(70) TYPE 2 2 FORMAT('1','---WMU MATRIX ALGEBRA PROGRAM'/12X,'(20X20)'//' FOR HE 1LP TYPE HELP') C CALL USAGE('MATRIX') 1 TYPE 10 10 FORMAT(' *',$) READ(5,11)(RED(I),I=1,70) 11 FORMAT(70A1) K=1 DO 13 I=1,70 IF(RED(I).EQ.BLANK)GO TO 13 RED(K)=RED(I) K=K+1 13 CONTINUE DO 16 I=K,70 16 RED(I)=' ' IF(RED(1).EQ.'H'.AND.RED(2).EQ.'E'.AND.RED(3).EQ.'L'.AND. 1RED(4).EQ.'P')GO TO 1500 IF(RED(1).EQ.'R'.AND.RED(2).EQ.'E'.AND.RED(3).EQ.'A'.AND. 1RED(4).EQ.'D'.AND.RED(6).EQ.BLANK)GO TO 101 IF(RED(1).EQ.'T'.AND.RED(2).EQ.'Y'.AND.RED(3).EQ.'P'.AND. 1RED(4).EQ.'E'.AND.RED(6).EQ.BLANK)GO TO 201 IF(RED(1).EQ.'D'.AND.RED(2).EQ.'E'.AND.RED(3).EQ.'T'.AND. 1RED(5).EQ.BLANK)GO TO 301 IF(RED(2).EQ.'=')GO TO 401 IF(RED(1).EQ.'D'.AND.RED(2).EQ.'A'.AND.RED(3).EQ.'T'.AND.RED(4) 1.EQ.'A'.AND.RED(5).EQ.BLANK)GO TO 991 IF(RED(1).EQ.'T'.AND.RED(2).EQ.'R'.AND.RED(3).EQ.'A'.AND.RED(4).EQ 1.'C'.AND.RED(5).EQ.'E'.AND.RED(7).EQ.' ')GO TO 1011 TYPE 1002 1002 FORMAT(' ILLEGAL STATEMENT') GO TO 1 C C READ IN A MATRIX C 101 IF(IPT.EQ.0)GO TO 106 DO 109 I2=1,IPT IF(VAR(I2).EQ.RED(5))GO TO 108 109 CONTINUE 106 IPT=IPT+1 IF(IPT.GT.10)GO TO 994 VAR(IPT)=RED(5) I2=IPT 108 TYPE 102 102 FORMAT(' DIMENSIONS--',$) READ(5,103)(NDIM(I,I2),I=1,2) 103 FORMAT(2I) IF(NDIM(1,I2).GT.20.OR.NDIM(2,I2).GT.20)GO TO 150 TYPE 104 104 FORMAT(' MATRIX?'/) DO 107 J=1,NDIM(1,I2) 107 READ(5,105)(X(I2,J,K),K=1,NDIM(2,I2)) 105 FORMAT(20F) GO TO 1 150 TYPE 251 251 FORMAT(' DIMENSIONS MUST BE LESS THAN 20') GO TO 1 C C TYPE OUT A MATRIX C 201 DO 202 I=1,IPT IF(VAR(I).EQ.RED(5))GO TO 203 202 CONTINUE TYPE 204,RED(5) 204 FORMAT(' MATRIX ',A1,' NOT FOUND') GO TO 1 203 DO 207 J=1,NDIM(1,I) TYPE 206,(X(I,J,K),K=1,NDIM(2,I)) 206 FORMAT(' ',5F14.6) 207 TYPE 208 208 FORMAT(' ') GO TO 1 C C FIND THE DETERMINANT OF A MATRIX C 301 DO 302 I=1,IPT IF(VAR(I).EQ.RED(4))GO TO 303 302 CONTINUE TYPE 204,RED(4) GO TO 1 303 IF(NDIM(1,I).NE.NDIM(2,I))GO TO 350 DO 304 J=1,NDIM(1,I) DO 305 K=1,NDIM(2,I) A(J,K)=X(I,J,K) 305 CONTINUE 304 CONTINUE CALL MINVSQ(A,NDIM(1,I),.1,MC,MR,20,5,0,DET,IEXP) DET=DET*10.**IEXP TYPE 310,RED(4),DET 310 FORMAT(' DETERMINANT OF ',A1,' IS'G) GO TO 1 350 TYPE 351,RED(4) 351 FORMAT(' THE MATRIX IS NOT SQUARE') GO TO 1 C C SEARCH FOR OPERATOR C 401 IF(RED(3).EQ.'T'.AND.RED(4).EQ.'R'.AND.RED(5).EQ.'A'.AND. 1RED(6).EQ.'N'.AND.RED(7).EQ.'S'.AND.RED(9).EQ.BLANK)GO TO 501 IF(RED(3).EQ.'I'.AND.RED(4).EQ.'N'.AND.RED(5).EQ.'V'.AND. 1RED(7).EQ.BLANK)GO TO 601 IF(RED(4).EQ.'+'.AND.RED(6).EQ.BLANK)GO TO 701 IF(RED(4).EQ.'*'.AND.RED(6).EQ.BLANK)GO TO 801 IF(RED(4).EQ.'-'.AND.RED(6).EQ.BLANK)GO TO 901 TYPE 1002 GO TO 1 C C TRANSPOSE A MATRIX C 501 DO 504 I2=1,IPT IF(VAR(I2).EQ.RED(8))GO TO 510 504 CONTINUE TYPE 204,RED(8) GO TO 1 510 DO 502 I1=1,IPT IF(VAR(I1).EQ.RED(1))GO TO 503 502 CONTINUE 520 IPT=IPT+1 IF(IPT.GT.10)GO TO 994 VAR(IPT)=RED(1) I1=IPT 503 DO 530 I=1,NDIM(2,I2) DO 531 J=1,NDIM(1,I2) A(I,J)=X(I2,J,I) 531 CONTINUE 530 CONTINUE DO 532 I=1,NDIM(2,I2) DO 533 J=1,NDIM(1,I2) X(I1,I,J)=A(I,J) 533 CONTINUE 532 CONTINUE NDS=NDIM(2,I2) NDIM(2,I1)=NDIM(1,I2) NDIM(1,I1)=NDS GO TO 1 IND=0 C C INVERT A MATRIX C 601 DO 602 I2=1,IPT IF(VAR(I2).EQ.RED(6))GO TO 603 602 CONTINUE TYPE 204,RED(6) GO TO 1 603 DO 604 I1=1,IPT IF(VAR(I1).EQ.RED(1))GO TO 605 604 CONTINUE IPT=IPT+1 IF(IPT.GT.10)GO TO 994 IND=1 VAR(IPT)=RED(1) I1=IPT 605 IF(NDIM(1,I2).NE.NDIM(2,I2))GO TO 608 DO 606 I=1,NDIM(1,I2) DO 606 J=1,NDIM(2,I2) 606 A(I,J)=X(I2,I,J) CALL MINVSQ(A,NDIM(1,I2),.1,MC,MR,20,5,0,DET,IEXP) DO 607 I=1,NDIM(1,I2) DO 607 J=1,NDIM(2,I2) 607 X(I1,I,J)=A(I,J) NDIM(1,I1)=NDIM(1,I2) NDIM(2,I1)=NDIM(2,I2) GO TO 1 608 TYPE 351 IF(IND.NE.0)IPT=IPT-1 GO TO 1 C C ADD OR SUBTRACT TWO MATRICES C C---------------COME HERE FROM ST. 401+4 701 IND=0 FM=1 720 DO 702 I2=1,IPT IF(VAR(I2).EQ.RED(3))GO TO 703 702 CONTINUE TYPE 204,RED(3) GO TO 1 703 DO 704 I3=1,IPT IF(VAR(I3).EQ.RED(5))GO TO 705 704 CONTINUE TYPE 204,RED(5) GO TO 1 705 IF(NDIM(1,I2).NE.NDIM(1,I3).OR.NDIM(2,I2).NE.NDIM(2,I3))GO TO 707 DO 710I1=1,IPT IF(VAR(I1).EQ.RED(1))GO TO 712 710 CONTINUE IPT=IPT+1 IF(IPT.GT.10)GO TO 994 IND=1 VAR(IPT)=RED(1) I1=IPT 712 DO 713 I=1,NDIM(1,I2) DO 713 J=1,NDIM(2,I2) 713 X(I1,I,J)=X(I2,I,J)+FM*X(I3,I,J) NDIM(1,I1)=NDIM(1,I2) NDIM(2,I1)=NDIM(2,I2) GO TO 1 707 TYPE 708,RED(3),RED(5) 708 FORMAT(' DIMENSIONS OF ',A1,' AND ',A1,' ARE NOT THE SAME') GO TO 1 C C SUBTRACT C C---------------COME HERE FROM ST. 401+6 901 FM=-1 IND=0 GO TO 720 C C FIND THE PRODUCT OF TWO MATRICES C 801 IND=0 DO 802 I2=1,IPT IF(VAR(I2).EQ.RED(3))GO TO 803 802 CONTINUE TYPE 204,RED(3) GO TO 1 803 DO 804 I3=1,IPT IF(VAR(I3).EQ.RED(5))GO TO 805 804 CONTINUE TYPE 204 ,RED(5) GO TO 1 805 IF(NDIM(2,I2).NE.NDIM(1,I3))GO TO 850 DO 806 I1=1,IPT IF(VAR(I1).EQ.RED(1))GO TO 807 806 CONTINUE IPT=IPT+1 IF(IPT.GT.10)GO TO 994 IND=1 VAR(IPT)=RED(1) I1=IPT 807 ND1=NDIM(1,I2) ND2=NDIM(2,I3) DO 820 I=1,ND1 DO 820 J=1,ND2 A(I,J)=0.0 DO 820 K=1,NDIM(2,I2) 820 A(I,J)=A(I,J)+X(I2,I,K)*X(I3,K,J) DO 821 I=1,ND1 DO 822 J=1,ND2 X(I1,I,J)=A(I,J) 822 CONTINUE 821 CONTINUE NDIM(1,I1)=ND1 NDIM(2,I1)=ND2 GO TO 1 850 TYPE 851,RED(3),RED(5) 851 FORMAT(' ILLEGAL DIMENSIONS ON ',A1,' OR ',A1) GO TO 1 C C DATA ENTRY OPTION C 991 CALL IO(2,IDV,-1,-4,0,0) CALL GETFOR(-1,-4,IFMT,ISTD,32,2) IF(ISTD.EQ.1)IFMT(1)='(10F)' TYPE 902 902 FORMAT(' ENTER TYPE OF MATRIX'/3X, 1'1 - RAW SUMS OF SQUARES AND CROSS PRODUCTS'/3X, 2'2 - STANDARDIZED SUMS OF SQUARES AND CROSS PRODUCTS'/3X, 3'3 - COVARIANCES'/3X, 4'4 - CORRELATIONS'/) READ(5,903)NTO 903 FORMAT(I) 998 TYPE 904 904 FORMAT(' ENTER NUMBER OF VARIABLES'/) READ(5,903)NVAR IF(NVAR.GT.20.OR.NVAR.LT.1) GO TO 998 TYPE 905 905 FORMAT(' ENTER MATRIX NAME'/) READ(5,906)ANA 906 FORMAT(A1) DO 907 I2=1,IPT IF(VAR(I2).EQ.ANA)GO TO 908 907 CONTINUE IPT=IPT+1 IF(IPT.GT.10)GO TO 994 I2=IPT 908 VAR(I2)=ANA NDIM(1,I2)=NVAR NDIM(2,I2)=NVAR K=0 DO 912 I=1,NVAR SUM(I)=0.0 DO 912 J=1,NVAR 912 X(I2,I,J)=0.0 IF(IDV.EQ.'TTY')TYPE 1017 1017 FORMAT(' ENTER DATA'/) IF(IDV.NE.'TTY') TYPE 1019 1019 FORMAT(' YOUR DATA IS BEING READ'/) IF(ISTD.EQ.1)TYPE 985 985 FORMAT(' (10 PER LINE)'/) 911 READ(2,IFMT,END=950)(RED(I),I=1,NVAR) 910 FORMAT(10F) K=K+1 DO 914 I=1,NVAR SUM(I)=SUM(I)+RED(I) DO 914 J=1,NVAR 914 X(I2,I,J)=X(I2,I,J)+RED(I)*RED(J) GO TO 911 950 GO TO (1,952,952,952),NTO GO TO 992 952 DO 956 I=1,NVAR DO 956 J=1,NVAR 956 X(I2,I,J)=X(I2,I,J)-(SUM(I)*SUM(J)/FLOAT(K)) GO TO (1,1,953,953),NTO 953 DO 957 I=1,NVAR DO 957 J=1,NVAR 957 X(I2,I,J)=X(I2,I,J)/FLOAT(K-1) GO TO (1,1,1,954),NTO 954 DO 958 I=1,NVAR 958 SUM(I)=SQRT(X(I2,I,I)) DO 959 I=1,NVAR DO 959 J=1,NVAR 959 X(I2,I,J)=X(I2,I,J)/(SUM(I)*SUM(J)) GO TO 1 1011 DO 1012 I=1,IPT IF(VAR(I).EQ.RED(6))GO TO 1013 1012 CONTINUE TYPE 204,RED(6) GO TO 1 1013 IF(NDIM(1,I).NE.NDIM(2,I))GO TO 350 SUMM=0.0 DO 1014J=1,NDIM(1,I) 1014 SUMM=SUMM+X(I,J,J) TYPE 1015,VAR(I),SUMM 1015 FORMAT(' TRACE OF ',A1,' IS ',G) GO TO 1 992 TYPE 993 993 FORMAT(' NO SUCH OPTION') GO TO 1 994 TYPE 995 995 FORMAT(' MORE THAN 10 MATRICES IN USE!'/) IPT=10 GO TO 1 1500 TYPE 1501 1501 FORMAT(//7X,'COMMANDS:'//' READ A -- READ IN A MATRIX AND CALL I 1T A'/' TYPE A -- TYPE OUT MATRIX A'/' DET A --- CALCULATE THE 1DETERMINANT OF A'/' TRACE A - TYPE OUT THE TRACE OF SQUARE MATRI 1X A'/' B=TRANS A LET MATRIX B BE THE TRANSPOSE OF M 1ATRIX A'/' B=INV A - LET MATRIX B BE THE INVERSE OF MATRIX A'/' 1C=A+B --- LET MATRIX C BE THE SUM OF MATRICES A AND B'/' C=A-B 1--- LET MATRIX C BE THE DIFFERENCE OF MATRICES A AND B'/' C=A*B 1--- LET MATRIX C BE THE PRODUCT OF MATRICES A AND B'/' DATA ---- 1 ENTER DATA FROM WHICH A MATRIX WILL BE GENERATED'/' HELP ---- 1TYPE OUT THIS COMMAND LIST'//) GO TO 1 END C---------------A, N, NDIM, METHOD, IOUT, TOL ARE INPUT. C--------------- MR, MC, DET, IEXP ARE OUTPUT. A IS MODIFIED. SUBROUTINE MINVSQ(A,N,TOL,MC,MR,NDIM,IOUT,METHOD,DET,IEXP) C THIS SUBROUTINE INVERTS A SQUARE MATRIX WITHIN ITSELF. C IT IS A MODIFICATION OF MINV IN THE IBM SSP MANUAL. C A...IS MATRIX TO BE INVERTED. C DIMENSION FOR A IN MAINLINE MUST BE NDIM BY NDIM C MC,MR...ARE VECTORS REQUIRED BY THE SUBROUTINE FOR BOOKEEPING. C DIMENSION FOR MC,MR IN MAINLINE MUST BE NDIM (OR LARGER) C N...IS NUMBER OF ROWS IN MATRIX TO BE INVERTED. (N.LE.NDIM) C TOL...SHOULD BE SIMILAR IN MAGNITUDE TO SMALLEST NONZERO ELEMENT C IN MATRIX C DET...IS DETERMINANT OF MATRIX (IF DET RETURNED EQUALS ZERO, THE C INVERSE MATRIX DID NOT EXIST). C (DET IS STORED IN SCIENTIFIC NOTATION, WITH THE POWER OF 10 C STORED IN IEXP. THIS WAS NECESSITATED BY FREQUENT OVERFLOWS C ON THE EXPONENT) C METHOD...IS A SWITCH TO SELECT PIVOTING TECHNIQUE. C METHOD=0 FASTEST TECHNIQUE, LEAST ACCURATE C METHOD=1 SLOWER THAN 0, BUT MORE ACCURATE C METHOD=2 SLOWEST BUT BEST ACCURACY C IOUT...IS OUTPUT DEVICE SPECIFICATION C DIMENSION A(1),MC(1),MR(1) ZTOL=TOL*1.E-6 DET=1. IEXP=0 DO 1 I=1,N MR(I)=I 1 MC(I)=I KSGN=1 KK=-NDIM 7 DO 100 K=1,N KK=KK+NDIM NL=N IF (METHOD-1) 4,3,2 3 NL=K 2 AMAX=0. JJ=KK-NDIM DO 6 J=K,N JJ=JJ+NDIM DO 5 I=K,NL IJ=I+JJ IF (ABS(A(IJ)).LE.AMAX)GO TO 5 AMAX=ABS(A(IJ)) NR=I NC=J 5 CONTINUE 6 CONTINUE GO TO 10 4 II=KK-NDIM DO 62 I=K,N II=II+NDIM KI=II+K IF (ABS(A(KI)).GT.ZTOL) GO TO 11 62 CONTINUE 13 WRITE(IOUT,51) 51 FORMAT(1X,'INVERSE DOES NOT EXIST') DET=0. IEXP=0 RETURN 11 AMAX=A(KI) NR=K NC=I 10 IF (ABS(AMAX).LE.ZTOL) GO TO 13 IF (NR.EQ.K) GO TO 9 KSGN=-KSGN MR(K)=NR JJ=-NDIM DO 12 J=1,N JJ=JJ+NDIM KJ=K+JJ NRJ=NR+JJ B=A(KJ) A(KJ)=A(NRJ) 12 A(NRJ)=B 9 IF (NC.EQ.K) GO TO 22 KSGN=-KSGN MC(K)=NC NCNC=(NC-1)*NDIM DO 20 J=1,N JK=J+KK JNC=J+NCNC B=A(JK) A(JK)=A(JNC) 20 A(JNC)=B 22 KKK=K+KK D=A(KKK) DET=DET*D 205 IF (ABS(DET).LT.10.) GO TO 200 DET=DET/10. IEXP=IEXP+1 GO TO 205 200 IF (ABS(DET).GE.1.) GO TO 210 DET=DET*10. IEXP=IEXP-1 IF (IEXP-40) 200,13,13 210 IF (DET.EQ.0.) GO TO 13 DO 30 I=1,N IK=I+KK 30 A(IK)=A(IK)/D A(KKK)=1./D II=-NDIM DO 40 I=1,N II=II+NDIM KI=K+II C=A(KI) IF (I-K) 42,40,42 42 IF (C) 41,40,41 41 DO 50 J=1,N JI=J+II JK=J+KK A(JI)=A(JI)-C*A(JK) 50 CONTINUE A(KI)=-C/D 40 CONTINUE 100 CONTINUE DET=DET*FLOAT(KSGN) DO 155 K=N,1,-1 L=MC(K) IF (K-L) 150,155,150 150 DO 170 I=N,1,-1 II=(I-1)*NDIM LI=L+II KI=K+II B=A(LI) A(LI)=A(KI) 170 A(KI)=B 155 CONTINUE DO 175 K=N,1,-1 L=MR(K) IF (K-L) 180,175,180 180 LL=(L-1)*NDIM KK=(K-1)*NDIM DO 185 I=1,N IL=I+LL IK=I+KK B=A(IL) A(IL)=A(IK) 185 A(IK)=B 175 CONTINUE RETURN END