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

📄 dgwaveform.c

📁 计算高斯各阶导函数的C程序 Computing Gaussian derivative waveforms of any order. Dgwaveform efficiently cre
💻 C
字号:
/* * Copyright (c) 2007 by the Society of Exploration Geophysicists. * For more information, go to http://software.seg.org/2007/0004 . * You must read and accept usage terms at: * http://software.seg.org/disclaimer.txt before use. * * Revision history: * Original SEG version by Werner M. Heigl, Apache E&P Technology, * February 2007. */ #include "su.h"#include "segy.h"/*************************** self documentation *************************/char *sdoc[] = {" 	   								"," DGWAVEFORM - make Gaussian derivative waveform			"," 	   								"," dgwaveform >stdout  [optional parameters]				"," 									","									"," Optional parameters:							"," n=2    	order of derivative (n>=1)				"," fpeak=35	peak frequency						"," nfpeak=n*n	max. frequency = nfpeak * fpeak				"," nt=128	length of waveform					"," shift=0	additional time shift in s (used for plotting)		"," sign=1	use =-1 to change sign					"," verbose=0	=0 don't display diagnostic messages			","               =1 display diagnostic messages				"," Notes:								"," This code computes a waveform that is the n-th order derivative of a	"," Gaussian. The variance of the Gaussian is specified through its peak	"," frequency, i.e. the frequency at which the amplitude spectrum of the	"," Gaussian has a maximum. nfpeak is used to compute maximum frequency,	"," which in turn is used to compute the sampling interval. Increasing	"," nfpeak gives smoother plots. In order to have a (pseudo-) causal	"," pulse, the program computes a time shift equal to sqrt(n)/fpeak. An	"," additional shift can be applied with the parameter shift. A positive	"," value shifts the waveform to the right.				","									"," Examples:								"," 2-loop Ricker: dgwaveform n=1	>ricker2.su				"," 3-loop Ricker: dgwaveform n=2 >ricker3.su				"," Sonic transducer pulse: dgwaveform n=10 fpeak=300 >sonic.su		","									"," To display use suxgraph. For example:					"," dgwaveform n=10 fpeak=300 | suxgraph style=normal &			","									",NULL};/* Credits: * *	Werner M. Heigl, February 2007 **//************************ end self doc **********************************/voidderiv_gauss(double dt, int nt, double t0, float fpeak, int n, double *w,	    int sign, int verbose);voidhermite(double *h, double *h0, double *h1, double *t, int nt, int n,	double sigma);static segy tr;	/* structure of type segy that contains the waveform */intmain(int argc, char **argv){	int i;			/* loop variable			*/	int n;			/* order of derivative			*/	int nfpeak;		/* fmax = nfpeak*fpeak			*/	int nt;			/* length of time vector t[]		*/	int sign;		/* scalar for polarity			*/	int verbose;		/* flag for diagnostic messages		*/	float fmax;		/* max. frequency			*/	float fpeak;		/* peak frequency			*/	double dt;		/* sampling interval 			*/	double shift;		/* additional time shift		*/	double t0;		/* time delay				*/	double *w = NULL;	/* waveform and Gaussian		*/		/* Hook up getpar */	initargs(argc, argv);	requestdoc(0);		/* Get parameters and do setup */	if (!getparint("n",&n))			n = 2;	if (!getparfloat("fpeak",&fpeak))	fpeak = 35;	if (!getparint("sign",&sign))		sign = 1;	if (!getparint("nfpeak",&nfpeak))	nfpeak = n * n;	if (!getpardouble("shift",&shift))	shift = 0;	if (!getparint("verbose",&verbose))	verbose = 0;		fmax = nfpeak * fpeak;	dt = 0.5 / fmax;		t0 = shift + sqrt(n) / fpeak;	if (!getparint("nt",&nt))	nt = (int) (2 * t0 / dt + 1);	warn("n=%d fpeak=%.0f fmax=%.0f t0=%f nt=%d dt=%.12f",n,fpeak,fmax,t0,nt,dt);	if (dt < 1e-6)	err("single-precision exceeded: reduce nfpeak or fpeak");	/* allocate & initialize memory */	w = ealloc1double(nt);	memset((void *) w, '0', DSIZE * nt);	if (verbose)	warn("memory for waveform allocated and initialized");		/* compute waveform */	if (n >= 1) {				/* compute n-th derivative of Gaussian */		deriv_gauss(dt, nt, t0, fpeak, n, w, sign, verbose);			/* write out waveform */				for (i = 0; i < nt; ++i)	tr.data[i] = (float) w[i];			tr.tracl = 1;			tr.ns    = nt;			tr.trid  = 1;			tr.dt    = NINT(dt*1000000.0);			tr.ntr   = 1;			puttr(&tr);			warn("waveform written to stdout");						} else	err("specified n not >=1 !!");	/* free memory */	free1double(w);	if (verbose)	warn("memory freed");		return(CWP_Exit());}voidderiv_gauss(double dt, int nt, double t0, float fpeak, int n, double *w,	    int sign, int verbose)/****************************************************************************  deriv_gauss:  Compute n-th order derivative of a Gaussian.*****************************************************************************Input:dt		sampling intervalnt		length of waveform in samplest0		time shift for (pseudo-) causalityfpeak		maximum frequencyn		order of derivativesign		multiplier for polarity of waveformverbose		flag for diagnostic messages*****************************************************************************Output:w	array of size nt containing the waveform*****************************************************************************Return: none*****************************************************************************Author: Werner M. Heigl, Apache Corporation, E&P Technology, November 2006*****************************************************************************/{	int i;			/* loop variable			*/	double sigma;		/* temporal variance of Gaussian	*/	double C;		/* normalization constant		*/	double *h  = NULL;	/* Hermite polynomial			*/	double *h0 = NULL;	/* temp array for H_{n-1}		*/	double *h1 = NULL;	/* temp array for H_{n}			*/	double *t  = NULL;	/* time vector				*/		/* allocate & initialize memory */	t  = ealloc1double(nt);	h  = ealloc1double(nt);	h0 = ealloc1double(nt);	h1 = ealloc1double(nt);	memset((void *) t , '0', DSIZE * nt);	memset((void *) h , '0', DSIZE * nt);	memset((void *) h0, '0', DSIZE * nt);	memset((void *) h1, '0', DSIZE * nt);	if (verbose)		warn("memory allocated and initialized");	/* initialize time vector */	for (i = 0; i < nt; ++i)	t[i] = i * dt - t0;	if (verbose)	warn("t[] initialized");		/* compute Gaussian */	sigma = n / ( 4 * PI * PI * fpeak * fpeak );	if (verbose)	warn("sigma=%f",sigma);	for (i = 0; i < nt; ++i)	w[i] = exp( - t[i] * t[i] / (2 * sigma) );	if (verbose)	warn("Gaussian computed");		/* compute Hermite polynomial */	for (i = 0; i < nt; ++i) {		h0[i] = 1.0;		h1[i] = t[i] / sigma;	}	if (n==1)	memcpy((void *) h, (const void *) h1, DSIZE * nt);	if (n>1)	hermite(h, h0, h1, t, nt, n, sigma);	if (verbose)	warn("Hermite polynomial H_%d computed",n);		/* compute waveform */	for (i = 0; i < nt;++i)		w[i] = h[i] * w[i];	if (verbose)	warn("waveform computed");		/* find normalization constant */	C = fabs(w[0]);	for (i = 1; i < nt; ++i)		if (fabs(w[i]) > C)	C = fabs(w[i]);	if (ISODD(n))	C = -C;	/* to account for (-1)^n */	if (verbose)	warn("C=%f",C);		/* and finally normalize */	for (i = 0; i < nt; ++i)	w[i] = sign * w[i] / C;	if (verbose)	warn("waveform normalized");	/* check amplitude a t=0 */	if (verbose)	warn("w[o]=%.12f",w[0]);		/* free memory */	free1double(h); free1double(h0); free1double(h1);	free1double(t);	if (verbose)	warn("memory freed");}	voidhermite(double *h, double *h0, double *h1, double *t, int nt, int n, double sigma)/*********************************************************************************  hermite:  Compute n-th order generalized Hermite polynomial.**********************************************************************************Input:h0		array of size nt holding H_{n-1}h1		array of size nt holding H_{n}t		array of size nt holding time vectornt		size of arrays, no. of samplesn		order of polynomialsigma		variance**********************************************************************************Output:h		array of size nt holding H_{n+1}**********************************************************************************Note:	Note that n in the function call is the order of the derivative and        j in the code below is the n in the recurrence relation**********************************************************************************Author: Werner M. Heigl, Apache Corporation, E&P Technology, December 2006*********************************************************************************/{	int i;		/* loop variable */	int j=1;	/* recurrence counter */	/* as long as necessary use recurrence relation */	do {		/* current instance of recurrence relation */		for (i = 0; i < nt; ++i) 					h[i] = ( t[i] * h1[i] - j * h0[i] ) / sigma;				/* update inputs to recurrence relation */		memcpy((void *) h0, (const void *) h1, DSIZE * nt);		memcpy((void *) h1, (const void *) h , DSIZE * nt);				/* update counter */		++j;			} while (j < n);	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -