C @(#)OPTFIR.F 1.1 11/2/90 C C THIS PROGRAM DESIGNS OPTIMAL EQUIRRIPLE FIR DIGITAL FILTERS C DOUBLE PRECISION ATTN,RIPPLE,SVRIP DOUBLE PRECISION PI2,PI,AD,DEV,X,Y CHARACTER FNAME*100, ANSWER*1 COMMON DES,WT,ALPHA,IEXT,NFCNS,NGRID,PI2,AD,DEV,X,Y,GRID DIMENSION IEXT(100),AD(100),ALPHA(100),X(100),Y(100),H(100) DIMENSION DES(1600),GRID(1600),WT(1600) DIMENSION EDGE(20),FX(10),WTX(10),DEVIAT(10) PI=3.141592653589793 PI2=6.283185307179586 C MAXIMUM FILTER LENGTH NFMAX=256 WRITE (*,'(,A)') ' PROVISIONAL EQUIRRIPLE FILTER DESIGN ' WRITE (*,'(,A)') ' USE AT YOUR OWN RISK --------------- ' 100 CONTINUE WRITE (*,'(/,A)') ' ENTER NAME OF INPUT COMMAND FILE (PRESS FOR MANUAL ENTRY, ' WRITE (*,'(,A\)') ' SORRY, NO TILDE-EXPANSION. GIVE PATH RELATIVE + TO YOUR HOME OR STARTUP DIRECTORY): ' READ (*,'(A12)') FNAME IF (FNAME .EQ. ' ') THEN IO = 5 ELSE IO = 3 OPEN (3, FILE=FNAME) ENDIF WRITE (*,'(,A,/,20X,A)') ' ENTER FILTER TYPE (1=BANDPASS, 2=DIFFER +ENTIATOR,', '3=HILBERT TRANSFORMER, 4=HALF-BAND): ' READ (IO,*) JTYPE WRITE (*,'(,A)') ' ENTER FILTER LENGTH (ENTER 0 FOR ESTIMATE): ' READ (IO,*) NFILT IF(NFILT.GT.NFMAX.OR.(NFILT.LT.3.AND.NFILT.NE.0)) GO TO 515 WRITE (*,'(,A)') ' ENTER SAMPLING RATE OF FILTER: ' READ (IO,*) FS IF (JTYPE .EQ. 4) THEN NFILT = (NFILT + 1) / 2 NBANDS = 1 EDGE(1) = 0.0 WRITE (*,'(/,A\)') ' ENTER PASSBAND EDGE FREQUENCY: ' READ (IO,*) EDGE(2) EDGE(2) = 2.0 * EDGE(2) / FS FX(1) = 0.5 WTX(1) = 1.0 GO TO 118 ENDIF WRITE (*,'(,A)') ' ENTER NUMBER OF FILTER BANDS: ' READ (IO,*) NBANDS IF(NBANDS.LE.0) NBANDS=1 DO 115 I=1,NBANDS WRITE (*,'(,A,I3,A)') ' ENTER LOWER BAND EDGE FOR BAND', I, ': ' J=1+2*(I-1) READ (IO,*) EDGE(J) EDGE(J)=EDGE(J)/FS WRITE (*,'(,A,I3,A)') ' ENTER UPPER BAND EDGE FOR BAND', I, ': ' READ (IO,*) EDGE(J+1) EDGE(J+1)=EDGE(J+1)/FS WRITE (*,'(,A,I3,A)') ' ENTER DESIRED VALUE FOR BAND', I, ': ' READ (IO,*) FX(I) WRITE (*,'(,A,I3,A)') ' ENTER WEIGHT FACTOR FOR BAND', I, ': ' READ (IO,*) WTX(I) 115 CONTINUE WRITE (*,'(,A)') ' DO YOU WANT X/SIN(X) PREDISTORTION? (Y/N): ' READ (IO,'(A1)') ANSWER IF (ANSWER .EQ. 'Y' .OR. ANSWER .EQ. 'Y') IDIST=1 118 WRITE (*,'(,A)') ' ENTER NAME OF COEFFICIENT OUTPUT FILE ' WRITE (*,'(,A)') ' (SORRY, NO TILDE-EXPANSION. GIVE PATH RELATIVE +VE TO YOUR HOME DIRECTORY): ' READ (IO,'(A)') FNAME OPEN (1, FILE=FNAME) IF(NFILT.EQ.0) GO TO 120 NROX=0 GO TO 130 120 CONTINUE WRITE (*,'(,A)') ' ENTER DESIRED PASSBAND RIPPLE IN DB: ' READ (IO,*) RIPPLE WRITE (*,'(,A)') ' ENTER DESIRED STOPBAND ATTENUATION IN DB: ' READ (IO,*) ATTN RIPPLE=10.**(RIPPLE/20.) ATTN=10.**(-ATTN/20.) RIPPLE=(RIPPLE-1)/(RIPPLE+1) RIPPLE=DLOG10(RIPPLE) ATTN=DLOG10(ATTN) SVRIP=RIPPLE RIPPLE=(0.005309*(RIPPLE**2)+0.07114*RIPPLE-0.4761)*ATTN 1-(0.00266*(RIPPLE**2)+0.5941*RIPPLE+0.4278) ATTN=11.01217+0.51244*(SVRIP-ATTN) DELTAF=EDGE(3)-EDGE(2) NFILT=RIPPLE/DELTAF-ATTN*DELTAF+1 WRITE (*,'(/,A,I4)') ' ESTIMATED FILTER LENGTH = ', NFILT IF(NFILT.GT.NFMAX.OR.(NFILT.LT.3.AND.NFILT.NE.0)) GO TO 515 NROX=1 130 NEG=1 WRITE (*,'(/,A,/)') ' EXECUTING ...' IF(JTYPE .EQ. 1 .OR. JTYPE .EQ. 4) NEG = 0 NODD=NFILT/2 NODD=NFILT-2*NODD NFCNS=NFILT/2 IF(NODD.EQ.1.AND.NEG.EQ.0) NFCNS=NFCNS+1 GRID(1)=EDGE(1) DELF=16*NFCNS DELF=0.5/DELF IF(NEG.EQ.0) GO TO 135 IF(EDGE(1).LT.DELF)GRID(1)=DELF 135 CONTINUE J=1 L=1 LBAND=1 140 FUP=EDGE(L+1) 145 TEMP=GRID(J) DES(J)=EFF(TEMP,FX,LBAND,JTYPE,IDIST) WT(J)=WATE(TEMP,FX,WTX,LBAND,JTYPE) J=J+1 GRID(J)=TEMP+DELF IF(GRID(J).GT.FUP) GO TO 150 GO TO 145 150 GRID(J-1)=FUP DES(J-1)=EFF(FUP,FX,LBAND,JTYPE,IDIST) WT(J-1)=WATE(FUP,FX,WTX,LBAND,JTYPE) LBAND=LBAND+1 L=L+2 IF(LBAND.GT.NBANDS) GO TO 160 GRID(J)=EDGE(L) GO TO 140 160 NGRID=J-1 IF(NEG.NE.NODD) GO TO 165 IF(GRID(NGRID).GT.(0.5-DELF)) NGRID=NGRID-1 165 CONTINUE IF(NEG)170,170,180 170 IF(NODD.EQ.1) GO TO 200 DO 175 J=1,NGRID CHANGE=DCOS(PI*GRID(J)) DES(J)=DES(J)/CHANGE 175 WT(J)=WT(J)*CHANGE GO TO 200 180 IF(NODD.EQ.1) GO TO 190 DO 185 J=1,NGRID CHANGE=DSIN(PI*GRID(J)) DES(J)=DES(J)/CHANGE 185 WT(J)=WT(J)*CHANGE GO TO 200 190 DO 195 J=1,NGRID CHANGE=DSIN(PI2*GRID(J)) DES(J)=DES(J)/CHANGE 195 WT(J)=WT(J)*CHANGE 200 TEMP=FLOAT(NGRID-1)/FLOAT(NFCNS) DO 210 J=1,NFCNS 210 IEXT(J)=(J-1)*TEMP+1 IEXT(NFCNS+1)=NGRID NM1=NFCNS-1 NZ=NFCNS+1 CALL REMEZ(EDGE,NBANDS) IF(NEG) 300,300,320 300 IF(NODD.EQ.0) GO TO 310 DO 305 J=1,NM1 305 H(J)=0.5*ALPHA(NZ-J) H(NFCNS)=ALPHA(1) GO TO 350 310 H(1)=0.25*ALPHA(NFCNS) DO 315 J=2,NM1 315 H(J)=0.25*(ALPHA(NZ-J)+ALPHA(NFCNS+2-J)) H(NFCNS)=0.5*ALPHA(1)+0.25*ALPHA(2) GO TO 350 320 IF(NODD.EQ.0) GO TO 330 H(1)=0.25*ALPHA(NFCNS) H(2)=0.25*ALPHA(NM1) DO 325 J=3,NM1 325 H(J)=0.25*(ALPHA(NZ-J)-ALPHA(NFCNS+3-J)) H(NFCNS)=0.5*ALPHA(1)-0.25*ALPHA(3) H(NZ)=0.0 GO TO 350 330 H(1)=0.25*ALPHA(NFCNS) DO 335 J=2,NM1 335 H(J)=0.25*(ALPHA(NZ-J)-ALPHA(NFCNS+2-J)) H(NFCNS)=0.5*ALPHA(1)-0.25*ALPHA(2) 350 WRITE(6,360) 360 FORMAT(/' FINITE IMPULSE RESPONSE (FIR)'/ 1,' LINEAR PHASE DIGITAL FILTER DESIGN'/ 2,' REMEZ EXCHANGE ALGORITHM'/) IF(JTYPE.EQ.1) WRITE(6,365) 365 FORMAT(' BANDPASS FILTER'/) IF(JTYPE.EQ.2) WRITE(6,370) 370 FORMAT(' DIFFERENTIATOR'/) IF(JTYPE.EQ.3) WRITE(6,375) 375 FORMAT(' HILBERT TRANSFORMER'/) IF(JTYPE.EQ.4) WRITE(6,376) 376 FORMAT(' HALF-BAND FILTER'/) WRITE(6,378) NFILT 378 FORMAT(' FILTER LENGTH = ',I3/) IF(NROX.EQ.1) WRITE(6,379) 379 FORMAT(' FILTER LENGTH DETERMINED BY APPROXIMATION'/) WRITE(6,380) 380 FORMAT(' IMPULSE RESPONSE COEFFICIENTS:'/) DO 381 J=1,NFCNS K=NFILT+1-J IF(NEG.EQ.0) WRITE(6,382)J,H(J),K IF(NEG.EQ.1) WRITE(6,383)J,H(J),K 381 CONTINUE 382 FORMAT(10X,'H(',I3,') = ', E14.7,' = H(',I4,')') 383 FORMAT(10X,'H(',I3,') = ', E14.7,' = -H(',I4,')') IF(NEG.EQ.1.AND.NODD.EQ.1) WRITE(6,384) NZ, 0.0 384 FORMAT(10X,'H(',I3,') = ', E14.7) WRITE (*,*) C C DEBUG C C PAUSE 'PRESS TO CONTINUE ...' DO 450 K=1,NBANDS,4 KUP=K+3 IF(KUP.GT.NBANDS) KUP=NBANDS WRITE(6,385)(J,J=K,KUP) 385 FORMAT(25X,4('BAND',I3,8X)) WRITE(6,390)(EDGE(2*J-1),J=K,KUP) 390 FORMAT(/' LOWER BAND EDGE:',5F15.7) WRITE(6,395)(EDGE(2*J),J=K,KUP) 395 FORMAT(' UPPER BAND EDGE:',5F15.7) IF(JTYPE.NE.2) WRITE(6,400) (FX(J),J=K,KUP) 400 FORMAT(' DESIRED VALUE:',2X,5F15.7) IF(JTYPE.EQ.2) WRITE(6,405) (FX(J),J=K,KUP) 405 FORMAT(' DESIRED SLOPE:',2X,5F15.7) WRITE(6,410) (WTX(J),J=K,KUP) 410 FORMAT(' WEIGHT FACTOR:',2X,5F15.7) DO 420 J=K,KUP 420 DEVIAT(J)=DEV/WTX(J) WRITE(6,425) (DEVIAT(J),J=K,KUP) 425 FORMAT(' DEVIATION:',6X,5F15.7) DO 430 J=K,KUP IF(FX(J).EQ.1.0) DEVIAT(J)=(1.0+DEVIAT(J))/(1.0-DEVIAT(J)) 430 DEVIAT(J)=20.0*ALOG10(DEVIAT(J)) WRITE(6,435) (DEVIAT(J),J=K,KUP) 435 FORMAT(' DEVIATION IN DB:',5F15.7) 450 CONTINUE WRITE(6,455) (GRID(IEXT(J)),J=1,NZ) 455 FORMAT(/' EXTREMAL FREQUENCIES:'//(2X,5F12.7)) IF (NODD .EQ. 1) THEN IF (NEG .EQ. 1) NFCNS = NFCNS + 1 NCOEFF = 2 * NFCNS - 1 ELSE NCOEFF = 2 * NFCNS ENDIF IF (JTYPE .EQ. 4) THEN C C REMOVE THE WRITING OF THE FILTER LENGTH, FOR C COMPATIBILITY WITH GABRIEL C WRITE(1,500) 2 * NCOEFF - 1 C 500 FORMAT(I4) DO 502 I = 1, NCOEFF - 1 IF (I .LT. NFCNS) THEN WRITE (1,510) H(I) WRITE (1,510) 0.0 ELSEIF (I .EQ. NFCNS) THEN WRITE (1,510) H(I) WRITE (1,510) 0.5 WRITE (1,510) H(I) ELSE WRITE (1,510) 0.0 WRITE (1,510) H(NCOEFF-I) ENDIF 502 CONTINUE ELSE C C REMOVE THE WRITING OF THE FILTER LENGTH, FOR C COMPATIBILITY WITH GABRIEL C WRITE(1,500) NCOEFF C DO 505 I = 1, NCOEFF IF(I .LE. NFCNS) WRITE(1,510) H(I) IF(I .GT. NFCNS) THEN IF(NEG .EQ. 0) THEN WRITE(1,510) H(NCOEFF-I+1) ELSE WRITE(1,510) -H(NCOEFF-I+1) ENDIF ENDIF 505 CONTINUE ENDIF 510 FORMAT(1PE14.6) WRITE (*,*) GO TO 520 C C CATCH ERRORS C 515 PRINT *, '*** FILTER TOO LONG OR SHORT FOR PROGRAM ***' C C FIND OUT WHETHER TO TERMINATE PROGRAM C 520 CALL FLUSH(1) CLOSE(1) WRITE (*,'(/,A\)') ' ANOTHER DESIGN? (Y/N): ' READ (*,'(A1)') ANSWER IF (ANSWER .EQ. 'Y' .OR. ANSWER .EQ. 'Y') GO TO 100 STOP 'END OF PROGRAM' END C FUNCTION EFF(FREQ,FX,LBAND,JTYPE,IDIST) DIMENSION FX(10) IF(JTYPE.EQ.2) GO TO 1 EFF=FX(LBAND) IF(IDIST.EQ.0) RETURN X=3.141593*FREQ IF(X.NE.0) EFF=EFF*X/SIN(X) RETURN 1 EFF=FX(LBAND)*FREQ RETURN END C FUNCTION WATE(FREQ,FX,WTX,LBAND,JTYPE) DIMENSION FX(10),WTX(10) IF(JTYPE.EQ.2) GO TO 1 WATE=WTX(LBAND) RETURN 1 IF(FX(LBAND).LT.0.0001) GO TO 2 WATE=WTX(LBAND)/FREQ RETURN 2 WATE=WTX(LBAND) RETURN END C SUBROUTINE REMEZ(EDGE,NBANDS) DOUBLE PRECISION PI2,DNUM,DDEN,DTEMP,A,P,Q DOUBLE PRECISION D,AD,DEV,X,Y COMMON DES,WT,ALPHA,IEXT,NFCNS,NGRID,PI2,AD,DEV,X,Y,GRID DIMENSION EDGE(20) DIMENSION IEXT(100),AD(100),ALPHA(100),X(100),Y(100) DIMENSION DES(1600),GRID(1600),WT(1600) DIMENSION A(100),P(100),Q(100) ITRMAX=25 DEVL=-1.0 NZ=NFCNS+1 NZZ=NFCNS+2 NITER=0 100 CONTINUE IEXT(NZZ)=NGRID+1 NITER=NITER+1 IF(NITER.GT.ITRMAX) GO TO 400 DO 110 J=1,NZ DTEMP=GRID(IEXT(J)) DTEMP=DCOS(DTEMP*PI2) 110 X(J)=DTEMP JET=(NFCNS-1)/15+1 DO 120 J=1,NZ KID=J 120 AD(J)=D(KID,NZ,JET) DNUM=0.0 DDEN=0.0 K=1 DO 130 J=1,NZ L=IEXT(J) DTEMP=AD(J)*DES(L) DNUM=DNUM+DTEMP DTEMP=K*AD(J)/WT(L) DDEN=DDEN+DTEMP 130 K=-K DEV=DNUM/DDEN C C DEBUG C C WRITE(6,131) DEV C 131 FORMAT(1X,12HDEVIATION = ,F12.9) C NU=1 IF(DEV.GT.0.0) NU=-1 DEV=-NU*DEV K=NU DO 140 J=1,NZ L=IEXT(J) DTEMP=K*DEV/WT(L) Y(J)=DES(L)+DTEMP 140 K=-K IF(DEV.GE.DEVL) GO TO 150 CALL OUCH GO TO 400 150 DEVL=DEV JCHNGE=0 K1=IEXT(1) KNZ=IEXT(NZ) KLOW=0 NUT=-NU J=1 200 IF(J.EQ.NZZ) YNZ=COMP IF(J.GE.NZZ) GO TO 300 KUP=IEXT(J+1) L=IEXT(J)+1 NUT=-NUT IF(J.EQ.2) Y1=COMP COMP=DEV IF(L.GE.KUP) GO TO 220 ERR=GEE(L,NZ) ERR=(ERR-DES(L))*WT(L) DTEMP=NUT*ERR-COMP IF(DTEMP.LE.0.0) GO TO 220 COMP=NUT*ERR 210 L=L+1 IF(L.GE.KUP) GO TO 215 ERR=GEE(L,NZ) ERR=(ERR-DES(L))*WT(L) DTEMP=NUT*ERR-COMP IF(DTEMP.LE.0.0) GO TO 215 COMP=NUT*ERR GO TO 210 215 IEXT(J)=L-1 J=J+1 KLOW=L-1 JCHNGE=JCHNGE+1 GO TO 200 220 L=L-1 225 L=L-1 IF(L.LE.KLOW) GO TO 250 ERR=GEE(L,NZ) ERR=(ERR-DES(L))*WT(L) DTEMP=NUT*ERR-COMP IF(DTEMP.GT.0.0) GO TO 230 IF(JCHNGE.LE.0) GO TO 225 GO TO 260 230 COMP=NUT*ERR 235 L=L-1 IF(L.LE.KLOW) GO TO 240 ERR=GEE(L,NZ) ERR=(ERR-DES(L))*WT(L) DTEMP=NUT*ERR-COMP IF(DTEMP.LE.0.0) GO TO 240 COMP=NUT*ERR GO TO 235 240 KLOW=IEXT(J) IEXT(J)=L+1 J=J+1 JCHNGE=JCHNGE+1 GO TO 200 250 L=IEXT(J)+1 IF(JCHNGE.GE.0) GO TO 215 255 L=L+1 IF(L.GE.KUP) GO TO 260 ERR=GEE(L,NZ) ERR=(ERR-DES(L))*WT(L) DTEMP=NUT*ERR-COMP IF(DTEMP.LE.0.0) GO TO 255 COMP=NUT*ERR GO TO 210 260 KLOW=IEXT(J) J=J+1 GO TO 200 300 IF(J.GT.NZZ) GO TO 320 IF(K1.GT.IEXT(1)) K1=IEXT(1) IF(KNZ.LT.IEXT(NZ)) KNZ=IEXT(NZ) NUT1=NUT NUT=-NU L=0 KUP=K1 COMP=YNZ*(1.00001) LUCK=1 310 L=L+1 IF(L.GE.KUP) GO TO 315 ERR=GEE(L,NZ) ERR=(ERR-DES(L))*WT(L) DTEMP=NUT*ERR-COMP IF(DTEMP.LE.0.0) GO TO 310 COMP=NUT*ERR J=NZZ GO TO 210 315 LUCK=6 GO TO 325 320 IF(LUCK.GT.9) GO TO 350 IF(COMP.GT.Y1) Y1=COMP K1=IEXT(NZZ) 325 L=NGRID+1 KLOW=KNZ NUT=-NUT1 COMP=Y1*(1.00001) 330 L=L-1 IF(L.LE.KLOW) GO TO 340 ERR=GEE(L,NZ) ERR=(ERR-DES(L))*WT(L) DTEMP=NUT*ERR-COMP IF(DTEMP.LE.0.0) GO TO 330 J=NZZ COMP=NUT*ERR LUCK=LUCK+10 GO TO 235 340 IF(LUCK.EQ.6) GO TO 370 DO 345 J=1,NFCNS 345 IEXT(NZZ-J)=IEXT(NZ-J) IEXT(1)=K1 GO TO 100 350 KN=IEXT(NZZ) DO 360 J=1,NFCNS 360 IEXT(J)=IEXT(J+1) IEXT(NZ)=KN GO TO 100 370 IF(JCHNGE.GT.0) GO TO 100 400 CONTINUE NM1=NFCNS-1 FSH=1.0E-06 GTEMP=GRID(1) X(NZZ)=-2.0 CN=2.*NFCNS-1. DELF=1.0/CN L=1 KKK=0 IF(EDGE(1).EQ.0.0.AND.EDGE(2*NBANDS).EQ.0.5) KKK=1 IF(NFCNS.LE.3) KKK=1 IF(KKK.EQ.1) GO TO 405 DTEMP=DCOS(PI2*GRID(1)) DNUM=DCOS(PI2*GRID(NGRID)) AA=2.0/(DTEMP-DNUM) BB=-(DTEMP+DNUM)/(DTEMP-DNUM) 405 CONTINUE DO 430 J=1,NFCNS FT=(J-1)*DELF XT=DCOS(PI2*FT) IF(KKK.EQ.1) GO TO 410 XT=(XT-BB)/AA FT=ACOS(XT)/PI2 410 XE=X(L) IF(XT.GT.XE) GO TO 420 IF((XE-XT).LT.FSH) GO TO 415 L=L+1 GO TO 410 415 A(J)=Y(L) GO TO 425 420 IF((XT-XE).LT.FSH) GO TO 415 GRID(1)=FT A(J)=GEE(1,NZ) 425 CONTINUE IF(L.GT.1) L=L-1 430 CONTINUE GRID(1)=GTEMP DDEN=PI2/CN DO 510 J=1,NFCNS DTEMP=0.0 DNUM=(J-1)*DDEN IF(NM1.LT.1) GO TO 505 DO 500 K=1,NM1 500 DTEMP=DTEMP+A(K+1)*DCOS(DNUM*K) 505 DTEMP=2.0*DTEMP+A(1) 510 ALPHA(J)=DTEMP DO 550 J=2,NFCNS 550 ALPHA(J)=2.*ALPHA(J)/CN ALPHA(1)=ALPHA(1)/CN IF(KKK.EQ.1) GO TO 545 P(1)=2.0*ALPHA(NFCNS)*BB+ALPHA(NM1) P(2)=2.0*AA*ALPHA(NFCNS) Q(1)=ALPHA(NFCNS-2)-ALPHA(NFCNS) DO 540 J=2,NM1 IF(J.LT.NM1) GO TO 515 AA=0.5*AA BB=0.5*BB 515 CONTINUE P(J+1)=0.0 DO 520 K=1,J A(K)=P(K) 520 P(K)=2.0*BB*A(K) P(2)=P(2)+A(1)*2.0*AA JM1=J-1 DO 525 K=1,JM1 525 P(K)=P(K)+Q(K)+AA*A(K+1) JP1=J+1 DO 530 K=3,JP1 530 P(K)=P(K)+AA*A(K-1) IF(J.EQ.NM1) GO TO 540 DO 535 K=1,J 535 Q(K)=-A(K) Q(1)=Q(1)+ALPHA(NFCNS-1-J) 540 CONTINUE DO 543 J=1,NFCNS 543 ALPHA(J)=P(J) 545 CONTINUE IF(NFCNS.GT.3) RETURN ALPHA(NFCNS+1)=0.0 ALPHA(NFCNS+2)=0.0 RETURN END C DOUBLE PRECISION FUNCTION D(K,N,M) DOUBLE PRECISION AD,DEV,X,Y,Q,PI2 COMMON DES,WT,ALPHA,IEXT,NFCNS,NGRID,PI2,AD,DEV,X,Y,GRID DIMENSION IEXT(100),AD(100),ALPHA(100),X(100),Y(100) DIMENSION DES(1600),GRID(1600),WT(1600) D=1.0 Q=X(K) DO 3 L=1,M DO 2 J=L,N,M IF(J-K)1,2,1 1 D=2.0*D*(Q-X(J)) 2 CONTINUE 3 CONTINUE D=1.0/D RETURN END C FUNCTION GEE(K,N) DOUBLE PRECISION P,C,D,XF,PI2,AD,DEV,X,Y COMMON DES,WT,ALPHA,IEXT,NFCNS,NGRID,PI2,AD,DEV,X,Y,GRID DIMENSION IEXT(100),AD(100),ALPHA(100),X(100),Y(100) DIMENSION DES(1600),GRID(1600),WT(1600) P=0.0 XF=GRID(K) XF=DCOS(PI2*XF) D=0.0 DO 1 J=1,N C=XF-X(J) C=AD(J)/C D=D+C 1 P=P+C*Y(J) GEE=P/D RETURN END C SUBROUTINE OUCH C WRITE (*,'(/A)') ' ********** FAILURE TO CONVERGE **********' C WRITE (*,*) 'PROBABLE CAUSE IS MACHINE ROUNDING ERROR' C WRITE (*,*) 'THE IMPULSE RESPONSE MAY STILL BE CORRECT' RETURN END