You are on page 1of 36

C C C C C

PROGRAM TO RELOCATE EARTHQUAKES AND COMPUTE P AND S STATION CORRECTIONS. Author: J. Pujol TO COMPILE AND LINK IN DOUBLE PRECISION (on Sun Solaris) f77 -xtypemap=real:64,double:64,integer:64 -e sc-ps.f -o sc-ps include 'jhd-param.inc' DIMENSION UUT(MDIM,MDIM),SUUT(MDIM,MDIM),UR(MDIM),ZTZ(MDIM,MDIM), 1ZTR(MDIM),GI(MDIM,MDIM),Y(MDIM),STNM(MDIM), 1ALAT(MDIM),ALON(MDIM),AELEV(MDIM),PT(MDIM),PWT(MDIM),ST(MDIM), 1SWT(MDIM),IDW(MDIM),IDWP(MDIM),IDWS(MDIM),SDCUT(15), 1IWP(MDIM),IWS(MDIM),ISNP(MDIM),eELEV(MDIM),TPCOR(MDIM),TSCOR(MDIM) 1,TPC(MDIM),TSC(MDIM) COMMON S(MDIM),E(MDIM),U(MDIM,MDIM),V(MDIM,MDIM),WORK(MDIM),INFO, 1SCM(MDIM),PSXX(MDIM),PSYY(MDIM),IND(MDIM) COMMON /CORR/NSL2,R(MDIM),SCOR(MDIM),I2,elambda,IWTT,Pstnl(MDIM) 1,stnl(MDIM),neqtot,tvar,xxs(MDIM),yys(MDIM),avsd(20),SDLAR(20) 1,idlar(20),NNST,CUTSD,NSL,PSR,MAXG COMMON /RTELEV/IELRT,ELEV(MDIM) common/DIM/NITER,nstop,ICAR common /sv14/SV14MAX CHARACTER TITLE*80,PSTNL*5,STNM*4,STA*4,STNL*4 CHARACTER*32 FILENAME1,FILENAME2,FILENAME3 CHARACTER CARD*80,STAS*5,STAP*5 WRITE(9,*)' ---------- OUTPUT OF PROGRAM "SC-PS" ----------' WRITE(9,*)' ------------------------------------------------' OPEN(UNIT=20,NAME='for020.in',STATUS='OLD') READ(20,*)filename1,filename2,filename3 OPEN(UNIT=2,NAME=filename1,STATUS='OLD') OPEN(UNIT=4,NAME=filename2,STATUS='OLD') OPEN(UNIT=7,NAME=filename3,STATUS='OLD') WRITE(9,50) FILENAME1,FILENAME2,FILENAME3 FORMAT(/,' INPUT FILES:',/,'FOR002: ',A32,/,'FOR004: ',A32 1,/,'FOR007: ',A32,/) PRINT*,' ENTER MAX. # OF ITERATIONS, # OF EQ''S TO BE USED, and 1 1 FOR P+S OR 0 FOR P ONLY (OPTIONAL):' READ(20,*,ERR=150)NSTOP,MAXEQ,KPS GO TO 151 READ(20,*,ERR=150)NSTOP,MAXEQ KPS=1 If(maxeq.gt.LDIM)then print*,'Change dimension of PAR(4,LDIM) in subrotine LOCATE. STOP' stop end if DUMLEV=0 PRINT *,' ENTER MAX. COND. # FOR STA. CORR.( INTEGER); 0 FOR FREE 1INVERSION; # OF NON-0 S.V. TO CANCEL (NEGATIVE INTEGER):' read(20,*)Icondn WRITE(9,*)' ICONDN:', ICONDN PRINT *,' ENTER 1 TO CONSIDER STATION ELEVATIONS (IN KM) IN RAY TRACING 1 and 1 to use initial estimates of station corr.:' ! (optional):' READ(20,*,err=153)IELRT,iesc go to 154 READ(20,*)IELRT iesc=0 if(iesc.eq.1)then WRITE(9,*)' IELRT:',IELRT write(9,*)' INITIAL ESTIMATES OF STA. CORR. USED' else WRITE(9,*)' IELRT:',IELRT end if WRITE(8,52) FILENAME1,FILENAME2,FILENAME3,ICONDN,IELRT WRITE(3,52) FILENAME1,FILENAME2,FILENAME3,ICONDN,IELRT

50

150 151

153

154

52

WRITE(18,52) FILENAME1,FILENAME2,FILENAME3,ICONDN,IELRT WRITE(13,52) FILENAME1,FILENAME2,FILENAME3,ICONDN,IELRT format('''','SC-PS.',3(A15,';'),'ICONDN:',I4,'IELRT:',I1) PRINT *,' MAX. GAP and ENTER CUT-OFF S.D. FOR EACH ITER:' READ(20,*)MAXG,(SDCUT(I),I=1,NSTOP) WRITE(9,*) WRITE(9,29)MAXG FORMAT(' MAXIMUM GAP:',I5) WRITE(9,*) PRINT *,' ENTER MAX. SV(1)/SV(4) READ(20,*)SV14MAX WRITE(9,*)' MAX. SV(1)/SV(4) FOR WRITE(8,*)' MAX. SV(1)/SV(4) FOR WRITE(3,*)' MAX. SV(1)/SV(4) FOR FOR INDIVIDUAL EVENTS' INDIVIDUAL EVENTS:',SV14MAX INDIVIDUAL EVENTS:',SV14MAX INDIVIDUAL EVENTS:',SV14MAX

29

if(Icondn.EQ.0)then write(9,*)' Number of events:',maxeq,' elseIF(Icondn.GT.0)THEN write(9,*)' Number of events:',maxeq,' elseIF(Icondn.LT.0)THEN write(9,*)' Number of events:',maxeq,' 1,Icondn end if

"Free inversion".' Max. cond. #:',Icondn # OF S.V. CANCELED:'

80

11 13

MAXEQ1=MAXEQ+1 READ(4,80)CARD print*,' card:',card FORMAT(A80) READ(CARD,*,ERR=81)TITLE I2=0 if(i2.eq.0)WRITE(9,9)TITLE PRINT*,' ENTER INITIAL LAMBDA:' read(20,*)Elambda WRITE(9,11) FORMAT(/,' THE DATA HAVE BEEN WEIGHTED WITH HYPO71 WEIGHTS.',/) FORMAT(/,' THE DATA HAVE NOT BEEN WEIGHTED.',/)

C GENERATE A NEW STATION LIST HAVING AT LEAST ONE ARRIVAL TIME AND WITHOUT C P AND S WEIGHTS > OR = 4 SIMULTANEOUSLY. READ(2,*) READ(2,*)NSTN print*,' nstn:',nstn DO I=1,NSTN READ(2,*)STNM(I),ALAT(I),ALON(I),AELEV(I),TPCOR(I),TSCOR(I) if(iesc.eq.0)then TPCOR(I)=0 TSCOR(I)=0 end if END DO REWIND(2) READ(4,*) C INDEX IDW(I)=1 IF PWT(I) AND SWT(I) < 4, OR C IF STNM(I) RECORDED AT LEAST ONE EVENT DO I=1,NSTN IDW(I)=0 IDWP(I)=0 !INDEX FOR P WAVES IDWS(I)=0 !INDEX FOR S WAVES END DO max2=0 DO JJ=1,MAXEQ READ(4,80,end=180)CARD max2=max2+1 PRINT*,card READ(CARD,*,ERR=83)ID,NSTA PRINT*,' ID,NSTA:',ID,NSTA go to 79 write(29,*)' ERROR 85. ',CARD READ(CARD,*,ERR=83)ID,NSTA PRINT*,' ID,NSTA:',ID,NSTA

c 85

79

DO I=1,NSTA READ(4,80)CARD IF(KPS.EQ.0)then READ(CARD,*,ERR=85)STA,PT(I),PWT(I) SWT(I)=4 st(i)=-1 else READ(CARD,*,ERR=85)STA,PT(I),PWT(I),ST(I),SWT(I) end if IF(PWT(I).GE.4.AND.SWT(I).GE.4)GO TO 51 IWARN=0 DO J=1,NSTN IF(STA.EQ.STNM(J))THEN IDW(J)=1 IWARN=1 IF(IDWP(J).EQ.1.AND.IDWS(J).EQ.1)GO TO 51 IF(PWT(I).LT.4)IDWP(J)=1 IF(SWT(I).LT.4)IDWS(J)=1 GO TO 51 END IF END DO IF(IWARN.NE.1)THEN PRINT*,' STATION: ',STA,' NOT IN LIST!!!!!' WRITE(9,*),' STATION: ',STA,' NOT IN LIST!!!!!' END IF END DO READ(4,*) END DO maxeq=max2 write(9,*)' Actual number of events:',maxeq NSL=0 DO J=1,NSTN IF(IDW(J).EQ.1)THEN NSL=NSL+1 XXS(NSL)=ALON(J) YYS(NSL)=ALAT(J) TPC(NSL)=TPCOR(J) TSC(NSL)=TSCOR(J) eELEV(NSL)=AELEV(J) STNL(NSL)=STNM(J) IWP(NSL)=IDWP(J) IWS(NSL)=IDWS(J) IF(IDWP(J).NE.1)THEN WRITE(12,*)' STATION ',STNM(J),' DID NOT RECORD P ARRIVALS.' END IF IF(IDWS(J).NE.1)THEN WRITE(12,*)' STATION ',STNM(J),' DID NOT RECORD S ARRIVALS.' END IF END IF END DO

c 51

180

C C C C

GENERATE NEW STATION LIST TO DISTINGUISH BETWEEN P AND S ARRIVALS. STATIONS WITH P ARRIVALS LISTED FIRST, FOLLOWED BY STATIONS WITH S ARRIVALS. STATIONS WITHOUT P OR S ARRIVALS ARE NOT INCLUDED!!! JN=0 DO I=1,NSL IF(IWP(I).EQ.1)THEN JN=JN+1 PSTNL(JN)='P'//STNL(I) PSXX(JN)=XXS(I) PSYY(JN)=YYS(I) ELEV(JN)=eELEV(I) print*,pstnl(jn),psxx(jn),psyy(jn) SCOR(JN)=TPC(I) END IF END DO JNP=JN JNP1=JNP+1 DO I=1,NSL IF(IWS(I).EQ.1)THEN

JN=JN+1 ELEV(JN)=eELEV(I) PSTNL(JN)='S'//STNL(I) PSXX(JN)=XXS(I) PSYY(JN)=YYS(I) print*,pstnl(jn),psxx(jn),psyy(jn) SCOR(JN)=TSC(I) END IF END DO NSL2=JN PRINT*,' TOTAL NUMBER OF P AND (P + S) STATIONS:',JNP,NSL2 WRITE(9,*)' TOTAL NUMBER OF P AND (P + S) STATIONS:',JNP,NSL2 NITER=0 CONTINUE tvar=0 !initialize total variance neqtot=0 !total number of events at each iteration. RUR=0 DSD=0 NNST=0 NITER=NITER+1 CUTSD=SDCUT(NITER) AVSD(NITER)=0 SDLAR(NITER)=0 IF(NITER.GT.NSTOP)GO TO 100 DO K=1,NSL2 IND(K)=0 !INDEX TO TRACK STATIONS WITHOUT ARRIVALS END DO WRITE(9,31)NITER,ELAMBDA WRITE(6,31)NITER,ELAMBDA FORMAT(//,'***** ITER:',I4,' REWIND(4) READ(4,*) READ(4,*) FORMAT(A80,/) IEQ=0 IEQ2=0 DO I=1,NSL2 ZTR(I)=0 DO J=1,NSL2 ZTZ(I,J)=0 END DO END DO Y(1)=1 IF(Y(1).LT..01)GO TO 100

30 c

31

LAMBDA:',F8.6,' *****',//)

DO II=1,MAXEQ ieqq=ieq+1 if(ieqq.le.maxeq)CALL LOCATE(IEQ,KPS) C PRINT*,' IEQ:', IEQ IF(IEQ2.EQ.IEQ.OR.IEQ.EQ.MAXEQ1)THEN GO TO 10 ELSE IEQ2=IEQ C SET THE MATRICES NEEDED FOR THE STATION CORRECTIONS INVERSION. C DO U0*(U0)T FIRST. DO I=1,NSL2 DO J=1,NSL2 UUT(I,J)=0 END DO END DO DO I=1,NSL2 DO J=1,NSL2 DO K=1,4 UUT(I,J)=UUT(I,J)-U(I,K)*U(J,K) END DO END DO END DO DO I=1,NSL2 UUT(I,I)=1+UUT(I,I)

END DO C PREPARE RUUTR FOR THE COMPUTATION OF THE COVARIANCE MATRIX DO I=1,NSL2 DO K=1,NSL2 RUR=RUR+R(K)*UUT(K,I)*R(I) END DO END DO c REPLACE UUT BY SCM*UUT*SCM AND COMPUTE SUUT=SCM*UUT DO I=1,NSL2 DO J=1,NSL2 SUUT(I,J)=SCM(I)*UUT(I,J) UUT(I,J)=SUUT(I,J)*SCM(J) END DO END DO C print*,' II=',II,' ............................' C SET SUUT*R DO I=1,NSL2 UR(I)=0 DO K=1,NSL2 UR(I)=UR(I)+SUUT(I,K)*R(K) END DO END DO C SET ZTZ (=STS) AND ZTR (=STR) DO I=1,NSL2 ZTR(I)=ZTR(I)+UR(I) DO J=1,NSL2 ZTZ(I,J)=ZTZ(I,J)+UUT(I,J) UUT(I,J)=ZTZ(I,J) !SAVE ZTZ FOR COVARIANCE END DO END DO END IF END DO 10 CONTINUE 21 FORMAT(16F7.2) NC=NSL2 MR=NSL2 NC2=NC/2 CALL INVERSE(ZTZ,NSL2,GI,ICONDN) DO K=1,NSL2 IF(IND(K).EQ.0)WRITE(9,*)' STATION WITHOUT ARRIVAL: END DO DO J=1,NSL2 DO I=1,NSL2 V(I,J)=ZTZ(I,J) END DO END DO C COMPUTE THE SOLUTION VECTOR y = G' * ZTR DO I=1,NC Y(I)=0 DO K=1,MR Y(I)=Y(I)+GI(I,K)*ZTR(K) END DO END DO C COMPUTE (ds)^T S^TS ds FOR THE VARIANCE DSD=0 DO K=1,NSL2 DO I=1,NSL2 DSD=DSD+Y(K)*ZTZ(K,I)*Y(I) END DO END DO PRINT*,'NNST:',NNST DO I=1,NSL2 SCOR(I)=SCOR(I)+Y(I) !UPDATE STATION CORRECTIONS END DO WRITE(6,*)' STATION CORRECTIONS:' WRITE(6,20)(SCOR(I),I=1,NC) 20 FORMAT(10F8.2) AVSD(NITER)=AVSD(NITER)/neqtot

',PSTNL(K)

127

128

WRITE(6,127)AVSD(NITER),SDLAR(NITER),IDLAR(NITER),neqtot WRITE(9,127)AVSD(NITER),SDLAR(NITER),IDLAR(NITER),neqtot FORMAT(/,'....................................',/,' AVERAGE SD:', 1F6.2,' LARGEST SD:',F6.2,' IDNEQ:',I6,5x,'# OF EVENTS:',I5) WRITE(12,128)NITER,AVSD(NITER),SDLAR(NITER),IDLAR(NITER),NEQTOT FORMAT(' ITER #:',I4,' AVERAGE SD:',F6.2,' LARGEST SD:',F6.2, 1' IDNEQ:',I6,5x,'# OF EVENTS:',I5) niter1=niter+1 write(9,26)niter1 FORMAT(//,'###################################################### 1##########################',/,' station corrections for ITER #:' 1,i5,/) write(9,25)(PSTNL(I),scor(i),i=1,JNP) write(9,25)(PSTNL(I+NC2),scor(i+NC2),i=JNP1,NSL2) write(9,25)(PSTNL(I),scor(i),i=JNP1,NSL2) format(5(1X,A5,':',F7.3,2X)) iout=13 if(niter1.eq.nstop)iout=3 WRITE(iout,*)' Stat. corr. for ITER:',NITER1 DUM9=999.99 ISK=0 ISNP( ): INDEX FOR STATIONS WITHOUT P BUT WITH S ARRIVAL do k=jnp1,nsl2 ISNP(K)=1 end do DO J=1,JNP STAP=PSTNL(J) DO K=JNP1,NSL2 STAS=PSTNL(K) IF(STAP(2:5).EQ.STAS(2:5))THEN !SAME STATION WRITE(iout,143)STAP(2:5),psYY(J),psXX(J),ELEV(J),scor(J),scor(K) ISNP(K)=0 GO TO 110 END IF isk=1 END DO WRITE(iout,143)STAP(2:5),psYY(J),psXX(J),ELEV(J),scor(J),DUM9 END DO FORMAT(1X,'''',A4,'''',2F10.4,f10.3,2F10.2)

26

c 25

110 143

C IF ISK > 0, SOME STATIONS WITH S BUT NOT P ARRIVALS: IF(ISK.GT.0)THEN DO K=JNP1,NSL2 STAS=PSTNL(K) IF(ISNP(K).GT.0)WRITE(iout,143)STAS(2:5),psYY(K),psXX(K),ELEV(K) 1,DUM9,scor(K) END DO END IF sumsc=0 !sum of stat. corr. do i=1,nc sumsc=sumsc+scor(i) end do print*,' SUM OF STATION CORRECTIONS:',SUMSC WRITE(9,*) WRITE(9,*)' SUM OF STATION CORRECTIONS:',SUMSC write(9,126) FORMAT(//,'###################################################### 1##########################',/) I2=1 elambda=elambda*.5 GO TO 30 write(29,*)' ERROR 81. STOP',CARD GO TO 100 write(29,*)' ERROR 83. STOP',CARD GO TO 100 WRITE(12,*)' LAST ITERATION. STATIONS AND # OF ARRIVALS:' DO I=1,NSL2 WRITE(12,*)PSTNL(I),IND(I)

126 55

81 83

100

END DO STOP END C------------------------------------------------------------------------SUBROUTINE LOCATE(IEQ,KPS) C------------------------------------------------------------------------c PARAMETER (MDIM=250) include 'jhd-param.inc' DIMENSION DTDS(30),STNM(MDIM),XX(MDIM),YY(MDIM), 1SLO(30),STOP(30),A(MDIM,4),ATA(10,10),TOBS(MDIM), 1XVEC(10),WT(MDIM),C(MDIM,4),B(MDIM),SC(MDIM),PAR(4,LDIM),rwt(MDIM) 1,POBS(MDIM),PWT(MDIM),SOBS(MDIM),SWT(MDIM),IPS(MDIM),RPS(MDIM), 1 elcor(MDIM) DIMENSION STOPT(30),SLOT(30),ESLOT(30) COMMON /RTELEV/IELRT,ELEV(MDIM) COMMON S(MDIM),E(MDIM),U(MDIM,MDIM),V(MDIM,MDIM),WORK(MDIM),INFO, 1SCM(MDIM),PSXX(MDIM),PSYY(MDIM),IND(MDIM) c C C C C C C C C A(i,j): MATRIX OF DERIVATIVES. i REFERS TO STATION. j=1 ---> dt/dt; j=2 ---> dt/dx; j=3 ---> dt/dy; j=4 ---> dt/dz. B(i): VECTOR OF TIME RESIDUALS. B(i)= TOBS(i) - TCOMP(i). TOBS IS OBSERVED ARRIVAL TIME. TCOMP IS COMPUTED ARRIVAL TIME. TCOMP(i) = T0 + TRAVEL TIME FROM E.Q. TO STATION. XVEC: VECTOR OF CORRECTIONS DT,DX,DY,DZ. SCM: DIAGONAL IN THE MATRIX OF STATION CORRECTIONS. SCM(I)=1 IF THE STATION RECORDED THE EARTHQUAKE; 0 OTHERWISE. COMMON /CORR/NSL2,R(MDIM),SCOR(MDIM),I2,elambda,IWTT,Pstnl(MDIM) 1,stnl(MDIM),neqtot,tvar,xxs(MDIM),yys(MDIM),avsd(20),SDLAR(20) 1,idlar(20),NNST,CUTSD,NSL,VPSR,MAXG common/DIM/ITER,nstop,ICAR common /sv14/SV14MAX common /ttdrv/ dtdr,dtdz,dtds,INDPTH,TEST,LOWLR,JGO COMMON /SMODEL/NL,SLO,STOP,ESLO(30),ANGLE,PSR CHARACTER*4 STNM,STNL,STA(MDIM),card*80 CHARACTER*5 PSTNL,PSTNM(MDIM),STEMP IF(IEQ.GT.0)GO TO 999 IF(I2.EQ.1)GO TO 995 PSR=VPSR one=1 TEST=.0002 icar=0 CALL MODLIN 995 999 NEQ=0 read(4,*,END=998)IDNEQ,NSTA NNST=NNST+NSTA write(29,*)IDneq,NSTA NEQ=NEQ+1 PRINT*,' PROCESSING E.Q. #, ID:',NEQ,IDNEQ IEQ=IEQ+1 !COUNTER FOR THE # OF EQ's. go to 79 write(29,*)' ERROR 85. STOP',CARD READ(CARD,*)IDneq,NSTA PRINT*,' ID,NSTA:',IDneq,NSTA DO I=1,NSTA read(4,80)card write(29,*)card(1:50) IF(KPS.EQ.0)then READ(CARD,*,ERR=85)STA(I),POBS(I),PWT(I) SWT(I)=4 sobs(i)=-1 else READ(CARD,*,ERR=85)STA(I),POBS(I),PWT(I),SOBS(I),SWT(I) end if END DO FORMAT(A80)

!PROCESS A NEW

EARTHQUAKE

85

79 c

80

INS=0 DO I=1,NSTA C SKIP THE STATION IF IT IS NOT IN THE STATION LIST DO II=1,NSL2 STEMP=PSTNL(II) IF(STA(I).EQ.STEMP(2:5))GO TO 81 END DO GO TO 78 81 IF(PWT(I).LT.4)THEN INS=INS+1 IPS(INS)=1 !FOR USE WITH TTIME RPS(INS)=1 TOBS(INS)=POBS(I) WT(INS)=PWT(I) STNM(INS)=STA(I) PSTNM(INS)='P'//STA(I) END IF IF(SWT(I).LT.4)THEN INS=INS+1 IPS(INS)=2 !FOR USE WITH TTIME RPS(INS)=PSR TOBS(INS)=SOBS(I) WT(INS)=SWT(I) STNM(INS)=STA(I) PSTNM(INS)='S'//STA(I) END IF 78 END DO IF(ins.lt.4)THEN PRINT*,' LESS THAN 4 STATIONS. GO TO NEXT EVENT.' WRITE(12,*)' LESS THAN 4 STATIONS. GO TO NEXT EVENT.' PAR(1,NEQ)=TO PAR(2,NEQ)=XE PAR(3,NEQ)=YE PAR(4,NEQ)=Z read(4,*) IEQ=IEQ+1 GO TO 999 END IF AVWT=0 NSWT=0 DO I=1,INS WT(I)=(4-WT(I))*.25 IF(WT(I).NE.0)NSWT=NSWT+1 if(wt(i).lt.0)WT(I)=0 rwt(i)=sqrt(wt(i)) AVWT=AVWT+WT(I) AVWTr=AVWTr+rWT(I) !THE NORMAL EQNS. HAVE WEIGHTS WT(I) !!! END DO AVWT=AVWT/NSWT AVWTr=AVWTr/NSWT RWMAX=0 DO I=1,INS WT(I)=WT(I)/AVWT rWT(I)=rWT(I)/AVWTr IF(RWT(I).GT.RWMAX)RWMAX=RWT(I) END DO C WEIGTHS SHOULD BE < OR = 1 FOR EQ. A3 OF PAPER TO BE VALID. DO I=1,INS rWT(I)=rWT(I)/RWMAX END DO NSTA4=NSWT-4 IF(NSTA4.EQ.0)NSTA4=1 IF(I2.EQ.0)THEN read(4,80)card write(29,*)card(1:50) read(card,*)to,xe,ye,z read(card,*,err=82)aa,aa,aa,aa,IGAP IF(IPRINT.EQ.1)WRITE(9,8)IDNEQ,TO,XE,YE,Z JULY 26, 1991

82

jout=18 WRITE(jout,77)IDNEQ,nsta,TO,XE,YE,Z FORMAT(//,' EQ ID #:',I6,5X,' INITIAL ESTIMATES OF TO,XE,YE,Z:') ELSE READ(4,80)CARD READ(CARD,*,err=83)AA,AA,AA,AA,igap !RDUM,IDUM,IDUM,IGAP 83 TO=PAR(1,NEQ) XE=PAR(2,NEQ) YE=PAR(3,NEQ) Z=PAR(4,NEQ) PRINT*,'.....TO,XE,YE,Z,IGAP:',TO,XE,YE,Z,IGAP END IF C FIND X AND Y COORDINATES OF EQ STATIONS FROM STATION LIST. EQ STATIONS C NEED NOT BE ORDERED AS IN STATION LIST. do i=1,Ins DO II=1,NSL2 IF(PSTNL(II).EQ.PSTNM(I))THEN XX(I)=PSXX(II) YY(I)=PSYY(II) SC(I)=SCOR(II) elcor(i)=elev(ii) GO TO 2 END IF END DO 2 CONTINUE end do !end c 8 DO I=1,NSL2 B(I)=0 R(I)=0 END DO CONTINUE format (i3,10x,f5.2,2f6.3,1x,f4.1) write(10,*)'#' DO 43, I=1,INS IF(ICAR.EQ.1)THEN DX=XX(I)-XE DY=YY(I)-YE DELTA=SQRT(DX*DX+DY*DY) ELSE call delaz2(YE,XE,YY(i),XX(i),dx,dy,delta,1) END IF JPS=IPS(I) IF(IELRT.EQ.1)THEN DO J=1,NL STOPT(J)=STOP(J) ESLOT(J)=ESLO(J) SLOT(J)=SLO(J) END DO ZTEMP=Z NLTEMP=NL NL1=NL+1 NL2=NL+2 DO J=1,NL STOP(NL2-J)=STOP(NL1-J)+elcor(I) ESLO(NL2-J)=ESLO(NL1-J) SLO(NL2-J)=SLO(NL1-J) END DO STOP(1)=0 SLO(1)=SLO(2) ESLO(1)=ESLO(2) Z=Z+elcor(I) NL=NL+1 END IF JGO=0 TTIME = TTINVR(DELTA,Z,JPS) IF(IELRT.EQ.1)THEN NL=NLTEMP DO J=1,NL STOP(J)=STOPT(J) ESLO(J)=ESLOT(J)

111 25 C

SLO(J)=SLOT(J) END DO Z=ZTEMP END IF IF(JGO.EQ.1)THEN PRINT*,' DIVIDE BY ZERO IN TTINVR. GO TO NEXT EVENT.' WRITE(12,*)' DIVIDE BY ZERO IN TTINVR. GO TO NEXT EVENT.' PAR(1,NEQ)=TO PAR(2,NEQ)=XE PAR(3,NEQ)=YE PAR(4,NEQ)=Z IEQ=IEQ+1 GO TO 999 END IF

TTIME = TTINVR(DELTA,Z) TTIME=TTIME+TO+SC(I) !+elcor(i) 300 format(1x,'''',a4,'''',f10.3) B(I)=TOBS(I)-TTIME c print*,' TOBS(I),TTIME:',TOBS(I),TTIME if(abs(delta).lt.1.e-4)then if(delta.gt.0)then delta=0.0001 else delta=-0.0001 end if end if dtdx=-dtdr*dx/delta dtdy=-dtdr*dy/delta A(I,1)=1 A(I,2)=DTDX A(I,3)=DTDY A(I,4)=DTDZ 40 FORMAT (1X,A4,2X,F6.2,2X,f9.3,I5,5X,I5) 43 CONTINUE C COMPUTE VARIANCE VAR=0 DO I=1,INS VAR=VAR+WT(I)*B(I)**2 END DO SD=VAR/NSTA4 if(sd.lt.0)then print*,' ...... var,nsta4 ......',sd,nsta4 sd=999999 end if sd=sqrt(sd) IF(I2.EQ.0)then tempZ=Z if(tempz.le.0.OR.SD.GT.CUTSD.OR.IGAP.GT.MAXG)then write(12,12)ITER, IDNEQ,tempz,SD,IGAP FORMAT(' ITER, IDNEQ, DEPTH,SD,GAP:',2I6,F10.2,F8.2,I5) PAR(1,NEQ)=TO PAR(2,NEQ)=XE PAR(3,NEQ)=YE PAR(4,NEQ)=Z IEQ=IEQ+1 go to 999 END IF neqtot=neqtot+1 GO TO 112 end if

12

C COMPUTE ATA DO I=1,4 DO J=1,4 ATA(I,J)=0 DO K=1,INS ATA(I,J)=ATA(I,J)+WT(K)*A(K,I)*A(K,J) END DO IF(I.EQ.J)ATA(I,J)=ATA(I,J)+ELAMBDA

10

END DO END DO C COMPUTE ATB DO I=1,4 ATB=0 DO K=1,INS ATB=ATB+A(K,I)*B(K)*WT(K) END DO ATA(I,5)=ATB !AUGMENT MATRIX ATA WITH ATB BEFORE CALL TO EQUA END DO CALL EQUA(ATA,XVEC,4) XV1=ABS(XVEC(1)) XV2=ABS(XVEC(2)) XV3=ABS(XVEC(3)) XV4=ABS(XVEC(4)) 997 FORMAT(10F8.2) tempZ=Z+XVEC(4) if(tempz.le.0.OR.SD.GT.CUTSD.OR.IGAP.GT.MAXG)then write(12,12)ITER, IDNEQ,tempz,SD,IGAP PAR(1,NEQ)=TO PAR(2,NEQ)=XE PAR(3,NEQ)=YE PAR(4,NEQ)=Z go to 999 END IF neqtot=neqtot+1 TO=TO+XVEC(1) Z=Z+XVEC(4) IF(ICAR.EQ.0)THEN CALL DELAZ2(YE,XE,YE,XE,DLO,DLA,DDD,0) DLO=ABS(DLO) DLA=ABS(DLA) XVEC(2)=XVEC(2)/DLO XVEC(3)=XVEC(3)/DLA END IF XE=XE+XVEC(2) YE=YE+XVEC(3) 112 continue PRINT*,' SD:',SD AVSD(ITER)=AVSD(ITER)+SD IF(SD.GT.SDLAR(ITER))THEN SDLAR(ITER)=SD IDLAR(ITER)=IDNEQ END IF C C C C C C C C C C

Set new matrix C of derivatives having zeros for stations in the stations list that did not record the EQ. Stations that recorded the EQ will have the corresponding derivatives, originally stored in matrix A. Also set the diagonal elements of the station corrections matrix SCM and the vector of residuals R. In matrix C the first NSL lines will correspond to the P arrival contributions followed by the S arrival contributions. Same for matrix SCM and vector R. DO KK=1,NSL2 R(KK)=0 SCM(KK)=0 DO JJ=1,4 C(KK,JJ)=0 END DO END DO DO IK=1,NSL2 DO II=1,INS IF(PSTNL(IK).EQ.PSTNM(II))THEN DO KK=1,4 C(IK,KK)=A(II,KK)*rWT(II) END DO SCM(IK)=rWT(II) R(IK)=B(II)*rWT(II)

11

IND(IK)=IND(IK)+1 !INDEX TO TRACK STATION W/O ARRIVALS GO TO 3 END IF END DO CONTINUE END DO !end PAR(1,NEQ)=TO PAR(2,NEQ)=XE PAR(3,NEQ)=YE PAR(4,NEQ)=Z CALL SVD(C,NSL2,4) if(s(4).lt.1.e-5)then s(4)=1.e-5 sv14=10000 go to 14 end if sv14=s(1)/s(4) if(sv14.gt.SV14MAX)then write(12,13)ITER,IDNEQ,SD,IGAP,sv14 FORMAT(' ITER, IDNEQ ,SD,GAP,s(1)/s(4):',2I6,F8.2,i6,f8.1) neqtot=neqtot-1 go to 999 END IF IF(ITER.GT.1.AND.ITER.LT.3)THEN !23 july 1993 GO TO 243 ELSE jout=18 if(iter.eq.nstop)jout=8 WRITE(jout,77)IDNEQ,nsta,TO,XE,YE,Z,SD,ITER FORMAT(1X,2I6,3F10.3,F10.1,F7.2,I3,i10) iprint=0 IF(IPRINT.EQ.1)WRITE(9,7)IDNEQ,TO,XE,YE,Z FORMAT(/,' EQ ID #:',I6,5X,'TO,XE,YE,Z:',F10.2,2F10.3,F10.2,/) IF(IPRINT.EQ.1)WRITE(9,*)' RESIDUALS:' IF(IPRINT.EQ.1)WRITE(9,20)(STNM(I),B(I),I=1,INS) FORMAT(9(1X,A4,':',F6.2,2X)) IF(IPRINT.EQ.1)WRITE(9,26)SD FORMAT(' ***** SD:',F7.4) END IF CONTINUE !23 july 1993 IF(ITER.GT.1.AND.ITER.LT.6)THEN GO TO 998 ELSE FORMAT(/,' SINGULAR VALUES:',4F8.3) WRITE(6,200)(S(I),I=1,4)

14 13

77

20 26 243

200

iprint=0 IF(IPRINT.EQ.1)then WRITE(9,200)(S(I),I=1,4) write(9,*)'**********************************' write(9,*) end if END IF 998 CONTINUE RETURN END C ---------------------------------------------------------------------SUBROUTINE EQUA(A,X,N) !EQUA DIMENSION A(10,10),X(10) c DOUBLE PRECISION A NP=N+1 DO 9 I=1,N IP=I+1 DO 9 J=1,N IF(I-J)4,9,4 4 F=-A(J,I)/A(I,I) DO 3 K=IP,NP 3 A(J,K)=A(J,K)+F*A(I,K) 9 CONTINUE DO 10 I=1,N X(I)=A(I,N+1)/A(I,I)

12

10

CONTINUE RETURN END C ---------------------------------------------------------------------SUBROUTINE SVD(A,MR,NC) c PARAMETER (MDIM=250) include 'jhd-param.inc' DIMENSION A(MDIM,MDIM) COMMON S(MDIM),E(MDIM),U(MDIM,MDIM),V(MDIM,MDIM),WORK(MDIM),INFO, 1SCM(MDIM) COMMON /MDIM/MDIM1 CALL SSVDC(A,MR,MR,NC,S,E,U,NC,V,NC,WORK,11,INFO) CWRITE(3,*)' INFO:',INFO IF(MDIM1.NE.MDIM)THEN WRITE(12,112)MDIM,MDIM1 FORMAT(2i5,' STOP !!!, WRONG PARAMETER MDIM IN SSVDC. RECOMPILE 1SSVDC!!!') WRITE(3,112) WRITE(6,112) WRITE(8,112) STOP END IF iw=0 SORT SINGULAR VALUES AND THE CORRESPONDING VECTORS............... DO 45 K=1,NC G=-1 DO 39 I=K,NC IF(S(I).LT.G)GO TO 39 G=S(I) J=I CONTINUE IF(J.EQ.K)GO TO 45 S(J)=S(K) S(K)=G DO 140 I=1,MR Q=U(I,J) U(I,J)=U(I,K) U(I,K)=Q DO 142 I=1,NC Q=V(I,J) V(I,J)=V(I,K) V(I,K)=Q CONTINUE END OF SORTING .................................. SVMAX=S(1) SVMIN=S(NC) RETURN END

112

39

140

142 45 C

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE INVERSE(AA,NM,GI,IRATIO) C PROGRAM TO COMPUTE THE GENERALIZED INVERSE OF A SYMMETRIC MATRIX. c PARAMETER (MDIM=250) include 'jhd-param.inc' DIMENSION AA(MDIM,MDIM),GI(MDIM,MDIM),SV(MDIM),E(MDIM), 1U(MDIM,MDIM),ZZ(MDIM,MDIM) common/DIM/NITER,nstop,ICAR common /sv14/SV14MAX call tred2(mdim,nm,aa,sv,e,zz) call imtql2(mdim,nm,sv,e,zz,ierr) do j=1,mdim do k=1,mdim aa(k,j) = zz(k,j) end do end do C SV CONTAINS THE EIGENVALUES AND THE COLUMNS OF AA THE EIGENVECTORS IF(NITER.EQ.NSTOP-1)THEN NM2=NM/2

13

21

NM3=NM2+1 FORMAT(32F4.1) END IF

C FIND NUMBER OF SING. VALUES > 0 OR WITH COND. NUMBER < OR = RATIO IF(IRATIO.LT.0)THEN NSV=-IRATIO NP=NM-1-NSV GO TO 10 END IF 5 RATIO=IRATIO NP=0 DO I=1,NM IF(IRATIO.EQ.0)THEN IF(ABS(SV(I)).LT.1.E-5)GO TO 10 ELSE IF(ABS(SV(I)).LT.1.E-5)GO TO 10 IF(ABS(SV(1)/SV(I)).GT.RATIO)GO TO 10 END IF NP=NP+1 END DO 10 20 if(niter.ge.nstop-1)then FORMAT(10F8.2) end if WRITE(6,*)' NP, SV(1)/SV(NP):',NP,SV(1)/SV(NP) WRITE(6,20)(SV(I),I=1,NP) WRITE(6,23)(SV(I),I=NP+1,NM) WRITE(9,27)SV(1),NP,SV(NP),SV(1)/SV(NP) FORMAT(/,' SVMAX:',F10.2,5X,' NP:',I3,5X,' SV(NP):',F10.3,5x, 1'RATIO:',F10.2) write(9,24) format(/,' SINGULAR VALUES:') write(9,29)(SV(i),i=1,np) write(9,23)(SV(I),I=NP+1,NM) format(/,10f8.2) format(/,10f8.6)

27

24

29 23

C COMPUTE GENERALIZED INVERSE OF ORIGINAL MATRIX AA C DO (1/SV)*AA^T FIRST: DO I=1,NP DO J=1,NM u(I,J)=0 END DO END DO DO J=1,NM DO I=1,NP u(I,J)=(1./SV(I))*AA(J,I) END DO END DO C LEFT MULTIPLY BY AA NOW: DO 40 I=1,NM DO 40 J=1,NM GI(I,J)=0 DO K=1,NP GI(I,J)=GI(I,J)+AA(I,K)*U(K,J) END DO 40 CONTINUE RETURN END c************************************************************************** REAL function ttinvr(r,hpz,jps) c c --- ttinvr calculates minimum traveltime in arbitrary layered model. c source is depth -hpz- and receiver is offset distance -r- from c source. model consists of horizontal , plane parallel layers c (n-1 layers over homogeneous halfspace). c --- model is specified by c --- routine also calculates array containing nodes of minimum c traveltime path, an array of partial derivatives of travel c time with respect to all model slownesses, and partial derivatives

14

c with respect to source depth and range c --- program modified from ttlvz and including some conventions c used by chee wu chou for use in three-dimensional traveltime c calculations c c by robert s. crosson c geophysics program c university of washington c seattle, washington 98195 c april, 1979 c C Minor modifications from J. Pujol DIMENSION D(50),h(50) 1,slo(30),stop(30),dtds(30),rnod(60),znod(60) common /smodel/ nslay,slo,stop,eslo(30),angle,rps !rps: oct. 1990 common /ttdrv/ dtdr,dtdz,dtds,INDPTH,TEST,LOWLR,JGO common/DIM/XDIM,VDIM data test/0.0002/ TEST=TEST/XDIM !XDIM NON-DIMENSIONALIZING FACTOR jps = 1 for p wave 2 for s wave angle = sin takeoff angle --- note following conventions indpth = 2 if path is refracted path 1 if path is direct path lowlr = index of lowest layer penetrated by raypath --- test is convergence criterion for direct ray path calculation when the direct ray gets within distance -test- of -r-, iteration stops. --- if source is above receiver, interchange elevations of source and receiver and set flag -sflgsflg = 1 if (hpz.ge.stop(1)) go to 95 t1 = hpz rr = r hpz = stop(1) stop(1) = t1 sflg = -1 continue reverse p and s slowness for s waves if(jps.eq.2)call rev(slo,eslo,nslay) locate layer containing hypocenter and store index in lhpz. note that if hypocenter on a boundary, it is placed in overlying layer for refraction path calculation do 100 i=1,nslay if (hpz.le.stop(i)) go to 110 continue lhpz = nslay go to 120 lhpz = i-1 if(lhpz.eq.0) lhpz=1 continue assign layer thicknesses to internal array h only for those layers above source. lim = lhpz-1 do 130 i=1,lim h(i) = stop(i+1)-stop(i) continue h(lhpz) = abs(hpz-stop(lhpz)) !WAS DOUBLE PRECISION initialize for refraction path calculations indpth = 2 ttime = 1.0d+10 if source in halfspace, skip refracted ray calculations and go to direct ray calculation if (lhpz.eq.nslay) go to 220 prepare for loop which examines for all possible refracted paths (paths going below source) find maximum velocity (minimum slowness) from source to surface smin = 1.0d+35 do 140 i=1,lhpz smin = min(slo(i),smin) continue

c C C c c c c c c c c c c c c c

95 c c --c c

100

110 120 c --c

130 c ---

c --c c --c c ---

140

15

c --- no refraction path can exist off any deeper layer which has c slowness greater than all slownesses between layer and surface c (this would be low velocity zone) istrt = lhpz + 1 do 210 lay=istrt,nslay c --- check to see if low velocity criterion excludes refracted path if (slo(lay).ge.smin) go to 210 smin=slo(lay) p=smin c --- calculate partial slant distnaces, d(k) lim = lay-1 do 150 i=1,lim t1 = p/slo(i) t2 = t1*t1 c t3 = SQrt(1-t2) t3=sqrt((1-t1)*(1+t1)) d(i) = 2*(stop(i+1)-stop(i))/t3 150 continue c --- now calculate that part of slant distance from source to surface c using h array, and subtract out appropriate part from twice above do 160 i=1,lhpz t1 = p/slo(i) t2 = t1*t1 c t3 = SQrt(1-t2) t3 = SQrt((1-t1)*(1+t1)) d(i) = d(i)-h(i)/t3 160 continue c --- now d(i) array contains correct distribution of partial slant c distances for all layers. Calculate total offset distance sum = 0 do 170 i=1,lim t1 = p/slo(i) sum = d(i)*t1+sum 170 continue c --- sum now contains total offset distance. Compare against r if (sum-r) 180,180,210 180 continue c --- refraction path possible, assign final partial distance in lay d(lay)=r-sum c --- can now calculate total travel time by inner product of slant c path distances and slowness vector tt = dotf(d,1,slo,1,lay) c --- if travel time is a minimum, save partial path distances in c derivative array and go on to next possible refracted path if (ttime.le.tt) go to 210 ttime = tt do 190 i=lay,nslay dtds(i) = 0 190 continue do 200 i=1,lay dtds(i) = d(i) 200 continue dtdr = p angle=p/slo(lhpz) lowlr = lay c --- note that we can construct final node array from partial c derivative array, as well as reconstructing d array 210 continue c --- refraction path calculations are now completed. variable lowlr c contains the minimum time raypath bottom layer index and c dtds array contains the partial slant distances in all layers c --- proceed to calculate direct ray path for comparison. 220 continue do 230 i=1,nslay d(i) = 0 230 continue c --- if source in layer 1, use homogeneous layer calculation if (lhpz.gt.1) go to 240 c d(1) = SQrt(r*r+h(lhpz)*h(lhpz)) d(1) = SQrt((r+h(lhpz))*(r+h(lhpz)) - 2*h(lhpz)*r) p = 0 if (d(1).eq.0) go to 320 p = slo(lhpz)*r/d(1)

16

go to 320 c --- proceed to calculate direct path by iteration 240 continue c --- find minimum slowness between surface and source smin = slo(1) do 250 i=2,lhpz smin = min(smin,slo(i)) 250 continue c --- find maximum permissable value of p (p must lay between 0. c and pmax) pmax = smin p = 0.5d0*pmax c --- find a value of p which is greater than true p by half range c divide and test to see when ray emerges at distance greater c than r 260 p = (p+pmax)/2 sum = 0 do 270 i=1,lhpz isub=270 aslo=slo(i) t1 = p/slo(i) t2 = t1*t1 c t3 = sqrt(1.-t2) t3 = SQrt((1-t1)*(1+t1)) IF(t3.EQ.0)then jgo=1 ttinvr=999999 !jp oct. 1993 RETURN end if d(i) = h(i)/t3 c CALL ERRTST(73,JGO) ad=d(i) sum = d(i)*t1+sum 270 continue isub=2 if (r-sum) 280,310,260 280 continue c --- perform newton convergence on true p from top down. permit c no more than 20 iterations by nesting in do loop isub=6 ar=r do 300 i=1,20 isub=300 sder=0 sum=0 do 290 j=1,lhpz t1 = p/slo(j) t2 = t1*t1 c t3 = SQrt(1-t2) t3 = SQrt((1-t1)*(1+t1)) d(j) = h(j)/t3 ad=d(j) sum = d(j)*t1+sum den = (t3*t3*t3)*slo(j) aslo=slo(j) sder=h(j)/den+sder 290 continue isub=4 dmdpo = r-sum if (abs(dmdpo).lt.test) go to 310 !WAS DOUBLE p = dmdpo/sder+p 300 continue 310 continue isub=310 c --- p has now been found to sufficient accuracy, calculate direct c wave travel time and compare with refracted time to find minimum 320 continue tt = dotf(d,1,slo,1,lhpz) if (tt.gt.ttime) go to 350 c --- following code assumes direct wave time is minimum. Variables c are set and nodes are filled on this basis ttime = tt indpth = 1 nnod = lhpz+1

17

c ---

330

c c

340

345

350 c --c

c ---

360 c ---

c ---

370 c ---

c ---

znod(1) = hpz rnod(1)=0 znod(nnod) = stop(1) rnod(nnod) = r accumulates progressive range increments from source rsum = 0 lidx = lhpz lim = lhpz-1 do 330 i=1,lim lidx = lhpz-i+1 rsum = d(lidx)*p/slo(lidx)+rsum rnod(i+1) = rsum znod(i+1)=stop(lidx) continue dtdr = p t1=p/slo(lhpz) angle=t1 t1=t1*t1 dtdz = SQrt(1.d0-t1)*slo(lhpz) IF(T1.GT.1)THEN PRINT*,' >>>>>>>>>>>>>> T1:',T1 T1=1 END IF dtdz = SQrt((1 -t1)*(1 +t1))*slo(lhpz) t1=t1*t1 lowlr = lhpz do 340 i=1,nslay dtds(i) = d(i) continue ttinvr = ttime if (sflg.eq.1 ) go to 400 t1 = hpz hpz = stop(1) stop(1) = t1 dtdz = -dtdz call revarr(nnod,rnod) t1 = rnod(1) do 345 i=1,nnod rnod(i) = t1-rnod(i) continue call revarr(nnod,znod) go to 400 continue following code assumes refraction path is minimum time. nodes and derivatives are assigned on this basis p = dtdr angle = -p/slo(lhpz) nnod = 1 znod(1) = hpz rnod(1) = 0 reconstruct correct d(i) array from dtds array do 360 i=1,nslay d(i) = dtds(i) continue calculate offset to first layer below source t1 = stop(lhpz+1)-stop(lhpz) t2 = stop(lhpz+1)-hpz dtemp = t2/(t1+t2)*d(lhpz) rsum = 0 now assign nodes for points below source lim = lowlr-1 do 370 i=lhpz,lim rsum = dtemp*p/slo(i)+rsum nnod = nnod+1 rnod(nnod) = rsum znod(nnod) = stop(i+1) dtemp = d(i+1)/2 continue assign nodes for part of path in lowlr rsum = rsum+d(lowlr) nnod=nnod+1 rnod(nnod) = rsum znod(nnod) = stop(lowlr) work way back upgoing side of raypath

18

lim=lowlr-1 do 380 i=1,lim lidx = lowlr-i t1 = p/slo(lidx) t2 = t1*t1 c t3 = SQrt(1 -t2) t3 = SQrt((1 -t1)*(1 +t1)) rsum = (stop(lidx+1)-stop(lidx))*t1/t3+rsum nnod=nnod+1 rnod(nnod) = rsum znod(nnod) = stop(lidx) 380 continue c --- all nodes assigned, now assign derivatives t1 = (p/slo(lhpz))*(p/slo(lhpz)) c dtdz = -SQrt(1 -t1)*slo(lhpz) dtdz = -SQrt((1 -(p/slo(lhpz)))*(1 +(p/slo(lhpz))))*slo(lhpz) ttinvr = ttime isub=380 if (sflg.eq.1 ) go to 400 t1 = hpz hpz = stop(1) stop(1) = t1 call revarr(nnod,rnod) t1=rnod(1) do 385 i=1,nnod rnod(i) = t1-rnod(i) 385 continue call revarr(nnod,znod) 400 if(jps.eq.2)call rev(slo,eslo,nslay) c print*,' indpth,lowlr:',indpth,lowlr return end c********************************** subroutine rev(x,y,n) c dimension x(1),y(1) do 100 i=1,n temp=x(i) x(i)=y(i) y(i)=temp 100 continue return end c************************************* subroutine revarr(n,a) c c --- revarr reverses or inverts the order of elements in array a dimension a(n) lim = n/2 do 100 i=1,lim temp = a(i) index = n-i+1 a(i) = a(index) a(index) = temp 100 continue return end REAL function dotf(d,i,slo,j,n) DIMENSION d(1),slo(1) sum=0 do 100 ii=j,n 100 sum=sum + d(ii)*slo(ii) dotf=sum return end c c************************************************************************ subroutine modlin c************************************************************************** common/smodel/nl,slo,stop,eslo(30),angle,rps dimension vp(30),vs(30),d(30),slo(30),stop(30) character*70 card WRITE (6,*)'Enter velocity data base (i.e., crustal model file)' rewind 7

19

vpvs=rps nl=0 do 25 i=1,30 read(7,70,end=27)card 70 format(a70) read(card,*,err=50,end=27)d(i),vp(i),VPVS go to 60 50 read(card,*,end=27)d(i),vp(i) 60 vs(i)=vp(i)/VPVS nl=nl+1 25 continue 27 close(7) do 100 l=1,nl stop(l)=d(l) slo(l)=1./vp(l) eslo(l)=1./vs(l) 100 CONTINUE return end C SUBROUTINE TTINVRSUB.FOR C INCLUDES SUBROUTINES DELAZ... AND MODLIN c****************************************************************************** subroutine delaz2(elat,elon,slat,slon,dx,dy,delta,II) c common/DIM/XDIM,VDIM c c DELAZ CALCULATES DX,DY AND DELTA IF II=1 C " " DLAT,DLON IF II=0 c Don't forget -- longitude is latitude-dependent; therefore no need for an c average longitude c avlat=0.5*(elat+slat) a=1.840708+avlat*(.0015269+avlat*(-.00034+avlat*(1.02337e-6))) b=1.843404+avlat*(-6.93799e-5+avlat*(8.79993e-6+avlat*( 1-6.47527e-8))) A6=60*A B6=60*B IF(II.EQ.1)THEN dlat=slat-elat dlon=slon-elon dx=a6*dlon dy=b6*dlat delta=sqrt(dx*dx+dy*dy) return ELSE DX=A6 DY=B6 RETURN END IF end c------------------------------------------------------------------------------SUBROUTINE SSVDC(X,LDX,N,P,S,E,U,LDU,V,LDV,WORK,JOB,INFO) include 'jhd-param.inc' INTEGER LDX,N,P,LDU,LDV,JOB,INFO REAL X(mdim,mdim),S(mdim),E(mdim),U(mdim,mdim),V(mdim,mdim) 1,WORK(mdim) C C See LINPACK Users' Guide, J. Dongarra. C. Moler, J. Bunch, and G. Stewart, C SIAM, 1979 C C C C C C C C C C C C C C C SSVDC IS A SUBROUTINE TO REDUCE A REAL NXP MATRIX X BY ORTHOGONAL TRANSFORMATIONS U AND V TO DIAGONAL FORM. THE DIAGONAL ELEMENTS S(I) ARE THE SINGULAR VALUES OF X. THE COLUMNS OF U ARE THE CORRESPONDING LEFT SINGULAR VECTORS, AND THE COLUMNS OF V THE RIGHT SINGULAR VECTORS. ON ENTRY X REAL(LDX,P), WHERE LDX.GE.N. X CONTAINS THE MATRIX WHOSE SINGULAR VALUE DECOMPOSITION IS TO BE COMPUTED. X IS DESTROYED BY SSVDC. INTEGER. LDX IS THE LEADING DIMENSION OF THE ARRAY X.

LDX

20

C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C

LDU

INTEGER. ! Note: P and N P IS THE NUMBER OF COLUMNS OF THE MATRIX X. ! were inter! changed in the INTEGER. ! original. See N IS THE NUMBER OF ROWS OF THE MATRIX X. ! p. 11.4 of ! users' guide. INTEGER. LDU IS THE LEADING DIMENSION OF THE ARRAY U. (SEE BELOW). INTEGER. LDV IS THE LEADING DIMENSION OF THE ARRAY V. (SEE BELOW). REAL(N). WORK IS A SCRATCH ARRAY. INTEGER. JOB CONTROLS THE COMPUTATION OF THE SINGULAR VECTORS. IT HAS THE DECIMAL EXPANSION AB WITH THE FOLLOWING MEANING A.EQ.0 A.EQ.1 A.GE.2 B.EQ.0 B.EQ.1 DO NOT COMPUTE THE LEFT SINGULAR VECTORS. RETURN THE N LEFT SINGULAR VECTORS IN U. RETURN THE FIRST MIN(N,P) SINGULAR VECTORS IN U. DO NOT COMPUTE THE RIGHT SINGULAR VECTORS. RETURN THE RIGHT SINGULAR VECTORS IN V.

LDV

WORK

JOB

ON RETURN S REAL(MM), WHERE MM=MIN(N+1,P). THE FIRST MIN(N,P) ENTRIES OF S CONTAIN THE SINGULAR VALUES OF X ARRANGED IN DESCENDING ORDER OF MAGNITUDE. REAL(P). E ORDINARILY CONTAINS ZEROS. HOWEVER SEE THE DISCUSSION OF INFO FOR EXCEPTIONS. REAL(LDU,K), WHERE LDU.GE.N. IF JOBA.EQ.1 THEN K.EQ.N, IF JOBA.GE.2 THEN K.EQ.MIN(N,P). U CONTAINS THE MATRIX OF RIGHT SINGULAR VECTORS. U IS NOT REFERENCED IF JOBA.EQ.0. IF N.LE.P OR IF JOBA.EQ.2, THEN U MAY BE IDENTIFIED WITH X IN THE SUBROUTINE CALL. REAL(LDV,P), WHERE LDV.GE.P. V CONTAINS THE MATRIX OF RIGHT SINGULAR VECTORS. V IS NOT REFERENCED IF JOB.EQ.0. IF P.LE.N, THEN V MAY BE IDENTIFIED WITH X IN THE SUBROUTINE CALL. INTEGER. THE SINGULAR VALUES (AND THEIR CORRESPONDING SINGULAR VECTORS) S(INFO+1),S(INFO+2),...,S(M) ARE CORRECT (HERE M=MIN(N,P)). THUS IF INFO.EQ.0, ALL THE SINGULAR VALUES AND THEIR VECTORS ARE CORRECT. IN ANY EVENT, THE MATRIX B = TRANS(U)*X*V IS THE BIDIAGONAL MATRIX WITH THE ELEMENTS OF S ON ITS DIAGONAL AND THE ELEMENTS OF E ON ITS SUPER-DIAGONAL (TRANS(U) IS THE TRANSPOSE OF U). THUS THE SINGULAR VALUES OF X AND B ARE THE SAME.

INFO

LINPACK. THIS VERSION DATED 03/19/79 . G.W. STEWART, UNIVERSITY OF MARYLAND, ARGONNE NATIONAL LAB.

21

C C C C C C C C *

***** USES THE FOLLOWING FUNCTIONS AND SUBPROGRAMS. EXTERNAL SROT BLAS SAXPY,SDOT,SSCAL,SSWAP,SNRM2,SROTG FORTRAN ABS,AMAX1,MAX0,MIN0,MOD,SQRT INTERNAL VARIABLES INTEGER I,ITER,J,JOBU,K,KASE,KK,L,LL,LLS,LM1,LP1,LS,LU,M,MAXIT, MM,MM1,MP1,NCT,NCTP1,NCU,NRT,NRTP1 REAL SDOT,T REAL B,C,CS,EL,EMM1,F,G,SNRM2,SCALE,SHIFT,SL,SM,SN,SMM1,T1,TEST, * ZTEST LOGICAL WANTU,WANTV COMMON /MDIM/MDIM1 MDIM1=MDIm !J.P !J.P

SET THE MAXIMUM NUMBER OF ITERATIONS. MAXIT = 30 DETERMINE WHAT IS TO BE COMPUTED. WANTU = .FALSE. WANTV = .FALSE. JOBU = MOD(JOB,100)/10 NCU = N IF (JOBU .GT. 1) NCU = MIN0(N,P) IF (JOBU .NE. 0) WANTU = .TRUE. IF (MOD(JOB,10) .NE. 0) WANTV = .TRUE.

C C C C

REDUCE X TO BIDIAGONAL FORM, STORING THE DIAGONAL ELEMENTS IN S AND THE SUPER-DIAGONAL ELEMENTS IN E. INFO = 0 NCT = MIN0(N-1,P) NRT = MAX0(0,MIN0(P-2,N)) LU = MAX0(NCT,NRT) IF (LU .LT. 1) GO TO 170 DO 160 L = 1, LU LP1 = L + 1 IF (L .GT. NCT) GO TO 20

C C C C

COMPUTE THE TRANSFORMATION FOR THE L-TH COLUMN AND PLACE THE L-TH DIAGONAL IN S(L). S(L) = SNRM2(N-L+1,X(L,L),1) IF (S(L) .EQ. 0.0E0) GO TO 10 IF (X(L,L) .NE. 0.0E0) S(L) = SIGN(S(L),X(L,L)) CALL SSCAL(N-L+1,1.0E0/S(L),X(L,L),1) X(L,L) = 1.0E0 + X(L,L) CONTINUE S(L) = -S(L) CONTINUE IF (P .LT. LP1) GO TO 50 DO 40 J = LP1, P IF (L .GT. NCT) GO TO 30 IF (S(L) .EQ. 0.0E0) GO TO 30 APPLY THE TRANSFORMATION. T = -SDOT(N-L+1,X(L,L),1,X(L,J),1)/X(L,L) CALL SAXPY(N-L+1,T,X(L,L),1,X(L,J),1) CONTINUE PLACE THE L-TH ROW OF X INTO E FOR THE SUBSEQUENT CALCULATION OF THE ROW TRANSFORMATION. E(J) = X(L,J) CONTINUE CONTINUE IF (.NOT.WANTU .OR. L .GT. NCT) GO TO 70 PLACE THE TRANSFORMATION IN U FOR SUBSEQUENT BACK

10 20

C C C

30 C C C C 40 50 C C

22

C C

MULTIPLICATION. DO 60 I = L, N U(I,L) = X(I,L) CONTINUE CONTINUE IF (L .GT. NRT) GO TO 150 COMPUTE THE L-TH ROW TRANSFORMATION AND PLACE THE L-TH SUPER-DIAGONAL IN E(L). E(L) = SNRM2(P-L,E(LP1),1) IF (E(L) .EQ. 0.0E0) GO TO 80 IF (E(LP1) .NE. 0.0E0) E(L) = SIGN(E(L),E(LP1)) CALL SSCAL(P-L,1.0E0/E(L),E(LP1),1) E(LP1) = 1.0E0 + E(LP1) CONTINUE E(L) = -E(L) IF (LP1 .GT. N .OR. E(L) .EQ. 0.0E0) GO TO 120 APPLY THE TRANSFORMATION. DO 90 I = LP1, N WORK(I) = 0.0E0 CONTINUE DO 100 J = LP1, P CALL SAXPY(N-L,E(J),X(LP1,J),1,WORK(LP1),1) CONTINUE DO 110 J = LP1, P CALL SAXPY(N-L,-E(J)/E(LP1),WORK(LP1),1,X(LP1,J),1) CONTINUE CONTINUE IF (.NOT.WANTV) GO TO 140 PLACE THE TRANSFORMATION IN V FOR SUBSEQUENT BACK MULTIPLICATION. DO 130 I = LP1, P V(I,L) = E(I) CONTINUE CONTINUE CONTINUE CONTINUE CONTINUE SET UP THE FINAL BIDIAGONAL MATRIX OR ORDER M. M = MIN0(P,N+1) NCTP1 = NCT + 1 NRTP1 = NRT + 1 IF (NCT .LT. P) S(NCTP1) = X(NCTP1,NCTP1) IF (N .LT. M) S(M) = 0.0E0 IF (NRTP1 .LT. M) E(NRTP1) = X(NRTP1,M) E(M) = 0.0E0

60 70 C C C C

80

C C C

90

100

110 120 C C C C

130 140 150 160 170 C C C

C C C

IF REQUIRED, GENERATE U. IF (.NOT.WANTU) GO TO 300 IF (NCU .LT. NCTP1) GO TO 200 DO 190 J = NCTP1, NCU DO 180 I = 1, N U(I,J) = 0.0E0 180 CONTINUE U(J,J) = 1.0E0 190 CONTINUE 200 CONTINUE IF (NCT .LT. 1) GO TO 290 DO 280 LL = 1, NCT L = NCT - LL + 1 IF (S(L) .EQ. 0.0E0) GO TO 250 LP1 = L + 1 IF (NCU .LT. LP1) GO TO 220 DO 210 J = LP1, NCU T = -SDOT(N-L+1,U(L,L),1,U(L,J),1)/U(L,L)

23

210 220

230 240 250

260 270 280 290 300 C C C

CALL SAXPY(N-L+1,T,U(L,L),1,U(L,J),1) CONTINUE CONTINUE CALL SSCAL(N-L+1,-1.0E0,U(L,L),1) U(L,L) = 1.0E0 + U(L,L) LM1 = L - 1 IF (LM1 .LT. 1) GO TO 240 DO 230 I = 1, LM1 U(I,L) = 0.0E0 CONTINUE CONTINUE GO TO 270 CONTINUE DO 260 I = 1, N U(I,L) = 0.0E0 CONTINUE U(L,L) = 1.0E0 CONTINUE CONTINUE CONTINUE CONTINUE IF IT IS REQUIRED, GENERATE V. IF (.NOT.WANTV) GO TO 350 DO 340 LL = 1, P L = P - LL + 1 LP1 = L + 1 IF (L .GT. NRT) GO TO 320 IF (E(L) .EQ. 0.0E0) GO TO 320 DO 310 J = LP1, P T = -SDOT(P-L,V(LP1,L),1,V(LP1,J),1)/V(LP1,L) CALL SAXPY(P-L,T,V(LP1,L),1,V(LP1,J),1) CONTINUE CONTINUE DO 330 I = 1, P V(I,L) = 0.0E0 CONTINUE V(L,L) = 1.0E0 CONTINUE CONTINUE MAIN ITERATION LOOP FOR THE SINGULAR VALUES.

310 320

330 340 350 C C C

MM = M ITER = 0 360 CONTINUE C C C C C C C C QUIT IF ALL THE SINGULAR VALUES HAVE BEEN FOUND. ...EXIT IF (M .EQ. 0) GO TO 620 IF TOO MANY ITERATIONS HAVE BEEN PERFORMED, SET FLAG AND RETURN.

IF (ITER .LT. MAXIT) GO TO 370 INFO = M C ......EXIT GO TO 620 370 CONTINUE C C THIS SECTION OF THE PROGRAM INSPECTS FOR C NEGLIGIBLE ELEMENTS IN THE S AND E ARRAYS. ON C COMPLETION THE VARIABLES KASE AND L ARE SET AS FOLLOWS. C C KASE = 1 IF S(M) AND E(L-1) ARE NEGLIGIBLE AND L.LT.M C KASE = 2 IF S(L) IS NEGLIGIBLE AND L.LT.M C KASE = 3 IF E(L-1) IS NEGLIGIBLE, L.LT.M, AND C S(L), ..., S(M) ARE NOT NEGLIGIBLE (QR STEP). C KASE = 4 IF E(M-1) IS NEGLIGIBLE (CONVERGENCE). C DO 390 LL = 1, M L = M - LL

24

C 380 390 400

410

C 420 430 440

450

460

470 480 C C C C C C 490

...EXIT IF (L .EQ. 0) GO TO 400 TEST = ABS(S(L)) + ABS(S(L+1)) ZTEST = TEST + ABS(E(L)) IF (ZTEST .NE. TEST) GO TO 380 E(L) = 0.0E0 ......EXIT GO TO 400 CONTINUE CONTINUE CONTINUE IF (L .NE. M - 1) GO TO 410 KASE = 4 GO TO 480 CONTINUE LP1 = L + 1 MP1 = M + 1 DO 430 LLS = LP1, MP1 LS = M - LLS + LP1 ...EXIT IF (LS .EQ. L) GO TO 440 TEST = 0.0E0 IF (LS .NE. M) TEST = TEST + ABS(E(LS)) IF (LS .NE. L + 1) TEST = TEST + ABS(E(LS-1)) ZTEST = TEST + ABS(S(LS)) IF (ZTEST .NE. TEST) GO TO 420 S(LS) = 0.0E0 ......EXIT GO TO 440 CONTINUE CONTINUE CONTINUE IF (LS .NE. L) GO TO 450 KASE = 3 GO TO 470 CONTINUE IF (LS .NE. M) GO TO 460 KASE = 1 GO TO 470 CONTINUE KASE = 2 L = LS CONTINUE CONTINUE L = L + 1 PERFORM THE TASK INDICATED BY KASE. GO TO (490,520,540,570), KASE DEFLATE NEGLIGIBLE S(M). CONTINUE MM1 = M - 1 F = E(M-1) E(M-1) = 0.0E0 DO 510 KK = L, MM1 K = MM1 - KK + L T1 = S(K) CALL SROTG(T1,F,CS,SN) S(K) = T1 IF (K .EQ. L) GO TO 500 F = -SN*E(K-1) E(K-1) = CS*E(K-1) CONTINUE IF (WANTV) CALL SROT(P,V(1,K),1,V(1,M),1,CS,SN) CONTINUE GO TO 610 SPLIT AT NEGLIGIBLE S(L).

500 510 C C C 520

CONTINUE F = E(L-1) E(L-1) = 0.0E0

25

530 C C C 540 C C C *

DO 530 K = L, M T1 = S(K) CALL SROTG(T1,F,CS,SN) S(K) = T1 F = -SN*E(K) E(K) = CS*E(K) IF (WANTU) CALL SROT(N,U(1,K),1,U(1,L-1),1,CS,SN) CONTINUE GO TO 610 PERFORM ONE QR STEP. CONTINUE CALCULATE THE SHIFT. SCALE = AMAX1(ABS(S(M)),ABS(S(M-1)),ABS(E(M-1)),ABS(S(L)), ABS(E(L))) SM = S(M)/SCALE SMM1 = S(M-1)/SCALE EMM1 = E(M-1)/SCALE SL = S(L)/SCALE EL = E(L)/SCALE B = ((SMM1 + SM)*(SMM1 - SM) + EMM1**2)/2.0E0 C = (SM*EMM1)**2 SHIFT = 0.0E0 IF (B .EQ. 0.0E0 .AND. C .EQ. 0.0E0) GO TO 550 SHIFT = SQRT(B**2+C) IF (B .LT. 0.0E0) SHIFT = -SHIFT SHIFT = C/(B + SHIFT) CONTINUE F = (SL + SM)*(SL - SM) - SHIFT G = SL*EL CHASE ZEROS. MM1 = M - 1 DO 560 K = L, MM1 CALL SROTG(F,G,CS,SN) IF (K .NE. L) E(K-1) = F F = CS*S(K) + SN*E(K) E(K) = CS*E(K) - SN*S(K) G = SN*S(K+1) S(K+1) = CS*S(K+1) IF (WANTV) CALL SROT(P,V(1,K),1,V(1,K+1),1,CS,SN) CALL SROTG(F,G,CS,SN) S(K) = F F = CS*E(K) + SN*S(K+1) S(K+1) = -SN*E(K) + CS*S(K+1) G = SN*E(K+1) E(K+1) = CS*E(K+1) IF (WANTU .AND. K .LT. N) CALL SROT(N,U(1,K),1,U(1,K+1),1,CS,SN) CONTINUE E(M-1) = F ITER = ITER + 1 GO TO 610 CONVERGENCE.

550

C C C

* 560

C C C 570 C C C

CONTINUE MAKE THE SINGULAR VALUE POSITIVE.

580 C C C 590 C

IF (S(L) .GE. 0.0E0) GO TO 580 S(L) = -S(L) IF (WANTV) CALL SSCAL(P,-1.0E0,V(1,L),1) CONTINUE ORDER THE SINGULAR VALUE. IF (L .EQ. MM) GO TO 600 ...EXIT IF (S(L) .GE. S(L+1)) GO TO 600

26

T = S(L) S(L) = S(L+1) S(L+1) = T IF (WANTV .AND. L .LT. P) * CALL SSWAP(P,V(1,L),1,V(1,L+1),1) IF (WANTU .AND. L .LT. N) * CALL SSWAP(N,U(1,L),1,U(1,L+1),1) L = L + 1 GO TO 590 600 CONTINUE ITER = 0 M = M - 1 610 CONTINUE GO TO 360 620 CONTINUE RETURN END SUBROUTINE SAXPY(N,SA,SX,INCX,SY,INCY) C C C C C CONSTANT TIMES A VECTOR PLUS A VECTOR. USES UNROLLED LOOP FOR INCREMENTS EQUAL TO ONE. JACK DONGARRA, LINPACK, 3/11/78. REAL SX(1),SY(1),SA INTEGER I,INCX,INCY,IX,IY,M,MP1,N C IF(N.LE.0)RETURN IF (SA .EQ. 0.0) RETURN IF(INCX.EQ.1.AND.INCY.EQ.1)GO TO 20 C C C C CODE FOR UNEQUAL INCREMENTS OR EQUAL INCREMENTS NOT EQUAL TO 1 IX = 1 IY = 1 IF(INCX.LT.0)IX = (-N+1)*INCX + 1 IF(INCY.LT.0)IY = (-N+1)*INCY + 1 DO 10 I = 1,N SY(IY) = SY(IY) + SA*SX(IX) IX = IX + INCX IY = IY + INCY 10 CONTINUE RETURN C C C C C C CODE FOR BOTH INCREMENTS EQUAL TO 1

CLEAN-UP LOOP 20 M = MOD(N,4) IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M SY(I) = SY(I) + SA*SX(I) 30 CONTINUE IF( N .LT. 4 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,4 SY(I) = SY(I) + SA*SX(I) SY(I + 1) = SY(I + 1) + SA*SX(I + 1) SY(I + 2) = SY(I + 2) + SA*SX(I + 2) SY(I + 3) = SY(I + 3) + SA*SX(I + 3) 50 CONTINUE RETURN END SUBROUTINE SROT (N,SX,INCX,SY,INCY,C,S)

C C C C

APPLIES A PLANE ROTATION. JACK DONGARRA, LINPACK, 3/11/78. REAL SX(1),SY(1),STEMP,C,S INTEGER I,INCX,INCY,IX,IY,N

C IF(N.LE.0)RETURN IF(INCX.EQ.1.AND.INCY.EQ.1)GO TO 20

27

C C C C

CODE FOR UNEQUAL INCREMENTS OR EQUAL INCREMENTS NOT EQUAL TO 1 IX = 1 IY = 1 IF(INCX.LT.0)IX = (-N+1)*INCX + 1 IF(INCY.LT.0)IY = (-N+1)*INCY + 1 DO 10 I = 1,N STEMP = C*SX(IX) + S*SY(IY) SY(IY) = C*SY(IY) - S*SX(IX) SX(IX) = STEMP IX = IX + INCX IY = IY + INCY 10 CONTINUE RETURN

C C C

CODE FOR BOTH INCREMENTS EQUAL TO 1 20 DO 30 I = 1,N STEMP = C*SX(I) + S*SY(I) SY(I) = C*SY(I) - S*SX(I) SX(I) = STEMP 30 CONTINUE RETURN END SUBROUTINE SROTG(SA,SB,C,S)

C C C C C

CONSTRUCT GIVENS PLANE ROTATION. JACK DONGARRA, LINPACK, 3/11/78. REAL SA,SB,C,S,ROE,SCALE,R,Z ROE = SB IF( ABS(SA) .GT. ABS(SB) ) ROE = SA SCALE = ABS(SA) + ABS(SB) IF( SCALE .NE. 0.0 ) GO TO 10 C = 1.0 S = 0.0 R = 0.0 GO TO 20 10 R = SCALE*SQRT((SA/SCALE)**2 + (SB/SCALE)**2) R = SIGN(1.0,ROE)*R C = SA/R S = SB/R 20 Z = 1.0 IF( ABS(SA) .GT. ABS(SB) ) Z = S IF( ABS(SB) .GE. ABS(SA) .AND. C .NE. 0.0 ) Z = 1.0/C SA = R SB = Z RETURN END SUBROUTINE SSCAL(N,SA,SX,INCX)

C C C C C

SCALES A VECTOR BY A CONSTANT. USES UNROLLED LOOPS FOR INCREMENT EQUAL TO 1. JACK DONGARRA, LINPACK, 3/11/78. REAL SA,SX(1) INTEGER I,INCX,M,MP1,N,NINCX

C IF(N.LE.0)RETURN IF(INCX.EQ.1)GO TO 20 C C C CODE FOR INCREMENT NOT EQUAL TO 1 NINCX = N*INCX DO 10 I = 1,NINCX,INCX SX(I) = SA*SX(I) 10 CONTINUE RETURN C C C CODE FOR INCREMENT EQUAL TO 1

28

C C C

CLEAN-UP LOOP 20 M = MOD(N,5) IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M SX(I) = SA*SX(I) 30 CONTINUE IF( N .LT. 5 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,5 SX(I) = SA*SX(I) SX(I + 1) = SA*SX(I + 1) SX(I + 2) = SA*SX(I + 2) SX(I + 3) = SA*SX(I + 3) SX(I + 4) = SA*SX(I + 4) 50 CONTINUE RETURN END SUBROUTINE SSWAP (N,SX,INCX,SY,INCY)

C C C C C

INTERCHANGES TWO VECTORS. USES UNROLLED LOOPS FOR INCREMENTS EQUAL TO 1. JACK DONGARRA, LINPACK, 3/11/78. REAL SX(1),SY(1),STEMP INTEGER I,INCX,INCY,IX,IY,M,MP1,N

C IF(N.LE.0)RETURN IF(INCX.EQ.1.AND.INCY.EQ.1)GO TO 20 C C C C CODE FOR UNEQUAL INCREMENTS OR EQUAL INCREMENTS NOT EQUAL TO 1 IX = 1 IY = 1 IF(INCX.LT.0)IX = (-N+1)*INCX + 1 IF(INCY.LT.0)IY = (-N+1)*INCY + 1 DO 10 I = 1,N STEMP = SX(IX) SX(IX) = SY(IY) SY(IY) = STEMP IX = IX + INCX IY = IY + INCY 10 CONTINUE RETURN C C C C C C CODE FOR BOTH INCREMENTS EQUAL TO 1

CLEAN-UP LOOP 20 M = MOD(N,3) IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M STEMP = SX(I) SX(I) = SY(I) SY(I) = STEMP 30 CONTINUE IF( N .LT. 3 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,3 STEMP = SX(I) SX(I) = SY(I) SY(I) = STEMP STEMP = SX(I + 1) SX(I + 1) = SY(I + 1) SY(I + 1) = STEMP STEMP = SX(I + 2) SX(I + 2) = SY(I + 2) SY(I + 2) = STEMP 50 CONTINUE RETURN END

29

REAL FUNCTION SDOT(N,SX,INCX,SY,INCY) C C C C C FORMS THE DOT PRODUCT OF TWO VECTORS. USES UNROLLED LOOPS FOR INCREMENTS EQUAL TO ONE. JACK DONGARRA, LINPACK, 3/11/78. REAL SX(1),SY(1),STEMP INTEGER I,INCX,INCY,IX,IY,M,MP1,N C STEMP = 0.0E0 SDOT = 0.0E0 IF(N.LE.0)RETURN IF(INCX.EQ.1.AND.INCY.EQ.1)GO TO 20 C C C C CODE FOR UNEQUAL INCREMENTS OR EQUAL INCREMENTS NOT EQUAL TO 1 IX = 1 IY = 1 IF(INCX.LT.0)IX = (-N+1)*INCX + 1 IF(INCY.LT.0)IY = (-N+1)*INCY + 1 DO 10 I = 1,N STEMP = STEMP + SX(IX)*SY(IY) IX = IX + INCX IY = IY + INCY 10 CONTINUE SDOT = STEMP RETURN C C C C C C CODE FOR BOTH INCREMENTS EQUAL TO 1

CLEAN-UP LOOP 20 M = MOD(N,5) IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M STEMP = STEMP + SX(I)*SY(I) 30 CONTINUE IF( N .LT. 5 ) GO TO 60 40 MP1 = M + 1 DO 50 I = MP1,N,5 STEMP = STEMP + SX(I)*SY(I) + SX(I + 1)*SY(I + 1) + * SX(I + 2)*SY(I + 2) + SX(I + 3)*SY(I + 3) + SX(I + 4)*SY(I + 4) 50 CONTINUE 60 SDOT = STEMP RETURN END REAL FUNCTION SNRM2 ( N, SX, INCX) INTEGER NEXT REAL SX(1), CUTLO, CUTHI, HITEST, SUM, XMAX, ZERO, ONE DATA ZERO, ONE /0.0E0, 1.0E0/

C C C C C C C C C C C C C C C C C C C C C C

EUCLIDEAN NORM OF THE N-VECTOR STORED IN SX() WITH STORAGE INCREMENT INCX . IF N .LE. 0 RETURN WITH RESULT = 0. IF N .GE. 1 THEN INCX MUST BE .GE. 1 C.L.LAWSON, 1978 JAN 08 FOUR PHASE METHOD USING TWO BUILT-IN CONSTANTS THAT ARE HOPEFULLY APPLICABLE TO ALL MACHINES. CUTLO = MAXIMUM OF SQRT(U/EPS) OVER ALL KNOWN MACHINES. CUTHI = MINIMUM OF SQRT(V) OVER ALL KNOWN MACHINES. WHERE EPS = SMALLEST NO. SUCH THAT EPS + 1. .GT. 1. U = SMALLEST POSITIVE NO. (UNDERFLOW LIMIT) V = LARGEST NO. (OVERFLOW LIMIT) BRIEF OUTLINE OF ALGORITHM.. PHASE 1 SCANS ZERO COMPONENTS. MOVE TO PHASE 2 WHEN A COMPONENT IS NONZERO AND .LE. CUTLO MOVE TO PHASE 3 WHEN A COMPONENT IS .GT. CUTLO

30

C C C C C C C C C C C C C C C C C

MOVE TO PHASE 4 WHEN A COMPONENT IS .GE. CUTHI/M WHERE M = N FOR X() REAL AND M = 2*N FOR COMPLEX. VALUES FOR CUTLO AND CUTHI.. FROM THE ENVIRONMENTAL PARAMETERS LISTED IN THE IMSL CONVERTER DOCUMENT THE LIMITING VALUES ARE AS FOLLOWS.. CUTLO, S.P. U/EPS = 2**(-102) FOR HONEYWELL. CLOSE SECONDS ARE UNIVAC AND DEC AT 2**(-103) THUS CUTLO = 2**(-51) = 4.44089E-16 CUTHI, S.P. V = 2**127 FOR UNIVAC, HONEYWELL, AND DEC. THUS CUTHI = 2**(63.5) = 1.30438E19 CUTLO, D.P. U/EPS = 2**(-67) FOR HONEYWELL AND DEC. THUS CUTLO = 2**(-33.5) = 8.23181D-11 CUTHI, D.P. SAME AS S.P. CUTHI = 1.30438D19 DATA CUTLO, CUTHI / 8.232D-11, 1.304D19 / DATA CUTLO, CUTHI / 4.441E-16, 1.304E19 / DATA CUTLO, CUTHI / 4.441E-16, 1.304E19 / IF(N .GT. 0) GO TO 10 SNRM2 = ZERO GO TO 300

C 10 ASSIGN 30 TO NEXT SUM = ZERO NN = N * INCX C I = 1 20 GO TO NEXT,(30, 50, 70, 110) 30 IF( ABS(SX(I)) .GT. CUTLO) GO TO 85 ASSIGN 50 TO NEXT XMAX = ZERO C C C PHASE 1. SUM IS ZERO BEGIN MAIN LOOP

50 IF( SX(I) .EQ. ZERO) GO TO 200 IF( ABS(SX(I)) .GT. CUTLO) GO TO 85 C C ASSIGN 70 TO NEXT GO TO 105 C C C 100 I = J ASSIGN 110 TO NEXT SUM = (SUM / SX(I)) / SX(I) 105 XMAX = ABS(SX(I)) GO TO 115 C C C C C C C C PHASE 2. SUM IS SMALL. SCALE TO AVOID DESTRUCTIVE UNDERFLOW. PREPARE FOR PHASE 4. PREPARE FOR PHASE 2.

70 IF( ABS(SX(I)) .GT. CUTLO ) GO TO 75 COMMON CODE FOR PHASES 2 AND 4. IN PHASE 4 SUM IS LARGE. SCALE TO AVOID OVERFLOW. 110 IF( ABS(SX(I)) .LE. XMAX ) GO TO 115 SUM = ONE + SUM * (XMAX / SX(I))**2 XMAX = ABS(SX(I)) GO TO 200 C 115 SUM = SUM + (SX(I)/XMAX)**2 GO TO 200 C C C C C C C C C

PREPARE FOR PHASE 3. 75 SUM = (SUM * XMAX) * XMAX

FOR REAL OR D.P. SET HITEST = CUTHI/N FOR COMPLEX SET HITEST = CUTHI/(2*N)

31

85 HITEST = CUTHI/FLOAT( N ) C C C PHASE 3. SUM IS MID-RANGE. NO SCALING.

DO 95 J =I,NN,INCX IF(ABS(SX(J)) .GE. HITEST) GO TO 100 95 SUM = SUM + SX(J)**2 SNRM2 = SQRT( SUM ) GO TO 300 C 200 CONTINUE I = I + INCX IF ( I .LE. NN ) GO TO 20 C C C C C END OF MAIN LOOP. COMPUTE SQUARE ROOT AND ADJUST FOR SCALING. SNRM2 = XMAX * SQRT(SUM) 300 CONTINUE RETURN END c--------------subroutine tred2(nm,n,a,d,e,z) c integer i,j,k,l,n,nm real a(nm,n),d(n),e(n),z(nm,n) real f,g,h,hh,scale c c this subroutine is a translation of the algol procedure tred2, c num. math. 11, 181-195(1968) by martin, reinsch, and wilkinson. c handbook for auto. comp., vol.ii-linear algebra, 212-226(1971). c c this subroutine reduces a real symmetric matrix to a c symmetric tridiagonal matrix using and accumulating c orthogonal similarity transformations. c c on input c c nm must be set to the row dimension of two-dimensional c array parameters as declared in the calling program c dimension statement. c c n is the order of the matrix. c c a contains the real symmetric input matrix. only the c lower triangle of the matrix need be supplied. c c on output c c d contains the diagonal elements of the tridiagonal matrix. c c e contains the subdiagonal elements of the tridiagonal c matrix in its last n-1 positions. e(1) is set to zero. c c z contains the orthogonal transformation matrix c produced in the reduction. c c a and z may coincide. if distinct, a is unaltered. c c Questions and comments should be directed to Alan K. Cline, c Pleasant Valley Software, 8603 Altus Cove, Austin, TX 78759. c Electronic mail to cline@cs.utexas.edu. c c this version dated january 1989. (for the IBM 3090vf) c c -----------------------------------------------------------------c c? call xuflow(0) do 100 i = 1, n do 100 j = i, n 100 z(j,i) = a(j,i) c

32

110 c

do 110 i = 1, n d(i) = a(n,i)

do 300 i = n, 2, -1 l = i - 1 h = 0.0e0 scale = 0.0e0 if (l .lt. 2) go to 130 c .......... scale row (algol tol then not needed) .......... do 120 k = 1, l 120 scale = scale + abs(d(k)) c if (scale .ne. 0.0e0) go to 140 130 e(i) = d(l) c c" ( ignore recrdeps do 135 j = 1, l d(j) = z(l,j) z(i,j) = 0.0e0 z(j,i) = 0.0e0 135 continue c go to 290 c 140 do 150 k = 1, l d(k) = d(k) / scale h = h + d(k) * d(k) 150 continue c f = d(l) g = -sign(sqrt(h),f) e(i) = scale * g h = h - f * g d(l) = f - g c .......... form a*u .......... do 170 j = 1, l 170 e(j) = 0.0e0 c do 240 j = 1, l f = d(j) z(j,i) = f g = e(j) + z(j,j) * f c do 200 k = j+1, l g = g + z(k,j) * d(k) e(k) = e(k) + z(k,j) * f 200 continue c e(j) = g 240 continue c .......... form p .......... f = 0.0e0 c do 245 j = 1, l e(j) = e(j) / h f = f + e(j) * d(j) 245 continue c hh = -f / (h + h) c .......... form q .......... do 250 j = 1, l 250 e(j) = e(j) + hh * d(j) c .......... form reduced a .......... do 280 j = 1, l f = -d(j) g = -e(j) c do 260 k = j, l 260 z(k,j) = z(k,j) + f * e(k) + g * d(k) c d(j) = z(l,j) z(i,j) = 0.0e0 280 continue c

33

290 d(i) = h 300 continue c .......... accumulation of transformation matrices .......... do 500 i = 2, n l = i - 1 z(n,l) = z(l,l) z(l,l) = 1.0e0 h = d(i) if (h .eq. 0.0e0) go to 380 c do 330 k = 1, l 330 d(k) = z(k,i) / h c" ( ignore recrdeps c" ( prefer vector do 360 j = 1, l g = 0.0e0 c do 340 k = 1, l 340 g = g + z(k,i) * z(k,j) c g = -g c do 350 k = 1, l 350 z(k,j) = z(k,j) + g * d(k) 360 continue c 380 do 400 k = 1, l 400 z(k,i) = 0.0e0 c 500 continue c c" ( prefer vector do 520 i = 1, n d(i) = z(n,i) z(n,i) = 0.0e0 520 continue c z(n,n) = 1.0e0 e(1) = 0.0e0 return end subroutine imtql2(nm,n,d,e,z,ierr) c integer i,j,k,l,m,n,nm,ierr real d(n),e(n),z(nm,n) real b,c,f,g,p,r,s,tst1,tst2 c c this subroutine is a translation of the algol procedure imtql2, c num. math. 12, 377-383(1968) by martin and wilkinson, c as modified in num. math. 15, 450(1970) by dubrulle. c handbook for auto. comp., vol.ii-linear algebra, 241-248(1971). c c this subroutine finds the eigenvalues and eigenvectors c of a symmetric tridiagonal matrix by the implicit ql method. c the eigenvectors of a full symmetric matrix can also c be found if tred2 has been used to reduce this c full matrix to tridiagonal form. c c on input c c nm must be set to the row dimension of two-dimensional c array parameters as declared in the calling program c dimension statement. c c n is the order of the matrix. c c d contains the diagonal elements of the input matrix. c c e contains the subdiagonal elements of the input matrix c in its last n-1 positions. e(1) is arbitrary. c c z contains the transformation matrix produced in the c reduction by tred2, if performed. if the eigenvectors c of the tridiagonal matrix are desired, z must contain

34

c c c c c c c c c c c c c c c c c c c c c c c c c c c c c?

the identity matrix. on output d contains the eigenvalues in descending order. if an error exit is made, the eigenvalues are correct but unordered for indices 1,2,...,ierr-1. e has been destroyed. z contains orthonormal eigenvectors of the symmetric tridiagonal (or full) matrix. if an error exit is made, z contains the eigenvectors associated with the stored eigenvalues. ierr is set to zero for normal return, j if the j-th eigenvalue has not been determined after 30 iterations. Questions and comments should be directed to Alan K. Cline, Pleasant Valley Software, 8603 Altus Cove, Austin, TX 78759. Electronic mail to cline@cs.utexas.edu. this version dated january 1989. (for the IBM 3090vf) -----------------------------------------------------------------call xuflow(0) ierr = 0 if (n .eq. 1) go to 1001 do 100 i = 2, n 100 e(i-1) = e(i)

c e(n) = 0.0e0 c do 240 l = 1, n j = 0 c .......... look for small sub-diagonal element .......... 105 do 110 m = l, n-1 tst1 = abs(d(m)) + abs(d(m+1)) tst2 = tst1 + abs(e(m)) if (tst2 .eq. tst1) go to 120 110 continue c 120 p = d(l) if (m .eq. l) go to 240 if (j .eq. 30) go to 1000 j = j + 1 c .......... form shift .......... g = (d(l+1) - p) / (2.0e0 * e(l)) cccccccccccccccccccccccccccccccccccccccccccccccccccc c * r = pythag(g,1.0d0) cccccccccccccccccccccccccccccccccccccccccccccccccccc if (abs(g).le.1.0e0) then r = sqrt(1.0e0 + g*g) else r = g * sqrt(1.0e0 + (1.0e0/g)**2) endif cccccccccccccccccccccccccccccccccccccccccccccccccccc g = d(m) - p + e(l) / (g + sign(r,g)) s = 1.0e0 c = 1.0e0 p = 0.0e0 c .......... for i=m-1 step -1 until l do -- .......... do 200 i = m-1, l, -1 f = s * e(i) b = c * e(i) cccccccccccccccccccccccccccccccccccccccccccccccccccc c * r = pythag(f,g) cccccccccccccccccccccccccccccccccccccccccccccccccccc if (abs(f).ge.abs(g)) then r = abs(f) * sqrt(1.0e0 + (g/f)**2)

35

else if (g .ne. 0.0e0) then r = abs(g) * sqrt((f/g)**2 + 1.0e0) else r = abs(f) endif cccccccccccccccccccccccccccccccccccccccccccccccccccc e(i+1) = r if (r .eq. 0.0e0) then c .......... recover from underflow .......... d(i+1) = d(i+1) - p e(m) = 0.0e0 go to 105 endif s = f / r c = g / r g = d(i+1) - p r = (d(i) - g) * s + 2.0e0 * c * b p = s * r d(i+1) = g + p g = c * r - b c .......... form vector .......... do 180 k = 1, n f = z(k,i+1) z(k,i+1) = s * z(k,i) + c * f z(k,i) = c * z(k,i) - s * f 180 continue c 200 continue c d(l) = d(l) - p e(l) = g e(m) = 0.0e0 go to 105 240 continue c .......... order eigenvalues and eigenvectors .......... do 300 i = 1, n-1 k = i p = d(i) c do 260 j = i+1, n if (d(j) .le. p) go to 260 k = j p = d(j) 260 continue c d(k) = d(i) d(i) = p c do 280 j = 1, n p = z(j,i) z(j,i) = z(j,k) z(j,k) = p 280 continue c 300 continue c go to 1001 c .......... set error -- no convergence to an c eigenvalue after 30 iterations .......... 1000 ierr = l 1001 return end

36

You might also like