⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gplib.f

📁 linux环境下利用fortran语言开发
💻 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 + -