📄 gplib.f
字号:
* Copyright (c) Colorado School of Mines, 2007.* All rights reserved.* These routines are from the gplib library as revised by K. Araya* and Sebastien Geoltrain** We went in and quickly trapped a bunch of potentially illegal values,* however, this stuff should really be re-coded to be passing in* array lengths instead of hard-wiring work areas, etc. In the* pre-release version, a bad value of nsweep in klaud86 could send* the computations into limbo. Credit to Darrell Kramer of Mobil on* this and some related problems. Jack Cohen, 08/04/89**-------------------------------------------------------------------* This subroutine performs the one-sided cross correlation of* two functions by FFT, Bartlet truncation:** Usage:* call corr86(x,lx,y,ly,z,lz)** x the first array* lx the length of the array x* y the second array to move (*)* ly the length of the array y* z the output array* lz length of the output array z** Note:* lx + lz - 1 must be less than or equal to 8192.*-----------------------------------------------------------------------** Author:* Source: /src/public/gplib* Revision: Sebastien Geoltrain Jan.22,1989*---------------------------------------------------------------------- subroutine corr86(x,lx,y,ly,z,lz) real x(1),y(1),z(1),times integer lx,ly,lz,n,i,leng complex w1(8192),w2(8192),w3(8192)* check length parameters if(lx .LE. 0 .OR. ly .LE. 0) then stop ' corr86: illegal lx or ly' endif* computes length of output as closest power of 2, not to * exceed 2**13 (i.e. 8192). leng=lx+ly-1 n=2 do 10 i=1,13 if(leng.le.n)then leng = n go to 1200 else n = n * 2 endif10 continue1200 continue if (lx .gt. 8192 .or. ly .gt. 8192 .or. leng .gt. 8192) then stop ' corr86: illegal lx, ly or leng' endif* clears work arrays do 3000 i=1,leng w1(i)=cmplx(0.0,0.0) w2(i)=cmplx(0.0,0.0) w3(i)=cmplx(0.0,0.0)3000 continue* moves input to work arrays do 4000 i=1,lx w1(i)=cmplx(x(i),0.0)4000 continue do 4100 i=1,ly w2(i)=cmplx(y(i),0.0)4100 continue* Fourier transforms both inputs call fft85(w1,leng,-1) call fft85(w2,leng,-1)* takes complex conjugate of second input do 4200 i=1,leng w2(i)=conjg(w2(i))4200 continue* multiplies first input and conjugate of second input * in frequency domain do 4300 i=1,leng w3(i)=w1(i)*w2(i)4300 continue* performs inverse FFT of resulting product call fft85(w3,leng,1)* outputs result as real array of length lz times=sqrt(float(leng)) do 4400 i=1,lz z(i)=times*real(w3(i))4400 continue return end*--------------------------------------------------------------* This subroutine computes the FFT of a function:** Usage:* call fft85(cx,lx,sign)** cx the input array (complex)* after the calling it is the output.* lx the length of the input array* sign (-1) forward transform* (1) inverse transform*-----------------------------------------------------------------** Author: J. Claerbout* Source: /src/public/gplib* Revision: Sebastien Geoltrain Jan.22,1989*----------------------------------------------------------------- subroutine fft85(cx,lx,sign) integer sign,lx,i,j,l,istep,m real sc complex cx(lx),carg,cw,ctemp j=1 sc=sqrt(1.e0/lx) do 30 i=1,lx if(i.gt.j) goto 10 ctemp=cx(j)*sc cx(j)=cx(i)*sc cx(i)=ctemp10 m=lx/220 if(j.le.m) goto 30 j=j-m m=m/2 if(m.ge.1) goto 2030 j=j+m l=140 istep=2*l do 50 m=1,l carg=(0.e0,1.e0)*(3.14159265e0*sign*(m-1))/l cw=cexp(carg) do 50 i=m,lx,istep ctemp=cw*cx(i+l) cx(i+l)=cx(i)-ctemp50 cx(i)=cx(i)+ctemp l=istep if(l.lt.lx) goto 40 return end*---------------------------------------------------------------------* This subroutine generates a two-sided Klauder wavelet* by a specified frequency array:** Usage:* call klaud86(wave,leng,del,nsweep,fl,fh,ialfa)** wave array* leng the length of the generated Klauder* wavelet (should be an odd number)* hardwired at 255 in trisubs.getarray* del sampling rate in seconds* nsweep length of original vibroseis sweep (le. 8192)* fl lower cut frequency* fh higher cut frequency* ialfa taper length (GE.2.and.le.500)*-----------------------------------------------------------------------** Author:* Source: /src/public/gplib* Revision: Sebastien Geoltrain Jan.22,1989*---------------------------------------------------------------------- subroutine klaud86(wave,leng,del,nsweep,fl,fh,ialfa) real wave(1),sweep(8192),w1(1024),fl,fh,del integer i,leng,lengs,lengh,lengh1,nsweep,ialfa,ifirst* parameter checks* if length is too big or too small, exit if(leng .LE. 2 .OR. leng .GT. 1024) then stop ' klauder86: leng illegal' endif * if length is even, resets to closest smaller odd number if(mod(leng,2).eq.0) then leng=leng-1 endif * if sampling rate is negative or null, exit if(del .LE. 0.e0) then stop ' klauder86: del illegal' endif* if sweep is too long or too short, exit if(nsweep .LE. 0 .OR. nsweep .GT. 8192) then stop ' klauder86: nsweep illegal' endif* if taper is too small or too large, exit if(ialfa .LT. 2 .OR. ialfa .GT. 500) then stop ' klauder86: ialfa illegal' endif * generates vibroseis sweep lengs = nsweep call vibro86(sweep,lengs,del,fl,fh,ialfa)* crosscorrelates the sweep lengh=leng/2+1 call corr86(sweep,lengs,sweep,lengs,w1,lengh) ifirst=2 call norm85(w1,lengh,1,lengh,ifirst)* makes output into a two-sided function lengh1=lengh-1 do 100 i=1,lengh1 wave(lengh+i)=w1(i+1) wave(lengh-i)=w1(i+1)100 continue wave(lengh)=1.e0 return end*--------------------------------------------------------------------------* This subroutine normalizes an array by its RMS energy, or the* first value in the array or by the largest magnitude in the * Array:** Usage:* call norm85(x,lx,is,ie,in)** x the input array* lx the length of array* is the initial point to generate factor* ie the last point to generate factor* in operation flag* = 1 normalizes by the RMS energy* = 2 normalizes by the first value* = 3 normalizes by the largest magnitude*---------------------------------------------------------------------------** Author:* Source: /src/public/gplib* Revision: Sebastien Geoltrain Jan.22,1989*--------------------------------------------------------------------------- subroutine norm85(x,lx,is,ie,in) integer lx,is,ie,in,i real x(lx),b,x1,p* test input parameters if(lx .LT. 1 .OR. is .GE. ie .OR. is .LE. 0 .OR. ie .GT. lx) then stop ' norm85: illegal parameters' endif if(in .EQ. 1) then p=0.e0 do 150 i=is,ie p=p+x(i)*x(i)150 continue p=sqrt(p) do 160 i=1,lx x(i)=x(i)/p160 continue else if(in .EQ. 2) then x1=x(is) if(x1 .NE. 0.e0) then do 250 i=1,lx x(i)=x(i)/x1250 continue endif else if(in .EQ. 3) then b=0.e0 do 350 i=is,ie b=amax1(abs(x(i)),b)350 continue do 360 i=1,lx x(i)=x(i)/b360 continue endif return endc------------------------------------------------------ subroutine fasthilbert(p,q,ntrace) integer n,ntrace,i2,l1,l2 real p(ntrace),q(ntrace),h(32),a,b call hilbertcoef(h) do5 i2=1,ntrace5 q(i2) = 0.0 do20 n=1,ntrace do30 i2=1,32,2 l1=n-i2 l2=n+i2 if(l1.le.0.or.l1.gt.ntrace) then a = 0.0 else a = p(l1) endif if(l2.le.0.or.l2.gt.ntrace) then b = 0.0 else b = p(l2) endif30 q(n) = q(n) + h(i2)*(a-b)20 continue return endc subroutine hilbertcoef(h) real h(32),opi,pi integer i2 pi = 3.1415927 opi = 2./pi do10 i2 = 1,32,210 h(i2) = -opi/i2*(0.42+0.52*cos(pi*i2/32.)+.08*cos(pi*i2/16.)) return endc*-----------------------------------------------------------* This subroutine generates a vibroseis linear sweep:** Usage:* call vibro86(sweep,leng,del,fa,fb,ltaper)** sweep the generated sweep output array* leng length of sweep: samples* del sampling rate, in seconds* fa starting cut-off frequency (no restriction)* in hertz* fb ending cut-off frequency (no restriction)* in hertz* ltaper sample length of 2 quadrant cosine taper* (0 = no taper)*--------------------------------------------------------------** Author:* Source: /src/public/gplib* Revision: Sebastien Geoltrain Jan.22,1989*-------------------------------------------------------------- subroutine vibro86(sweep,leng,del,fa,fb,ltaper) integer i,leng,ltaper,l real sweep(leng),fa,fb,t,f,durat,fbad,pi,pi2,weight,del pi = 3.1415927e0 pi2=pi*2.e0* tests input if(del .LT. 0.e0)then stop ' vibro86: illegal del' endif* computes sweep durat=(leng-1.e0)*del fbad=(fb-fa)/(durat*2.e0) do 10 i=1,leng t = (i-1)*del f = fa+fbad*t sweep(i) = cos(pi2*f*t)10 continue* applies taper do 20 i=1,ltaper-1 l=leng+1-i weight=.5e0-.5e0*cos(pi*(i-1)/(ltaper-1) ) sweep(i)=sweep(i)*weight sweep(l)=sweep(l)*weight20 continue return end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -