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

📄 convolution.c

📁 su 的源代码库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright (c) Colorado School of Mines, 2006.*//* All rights reserved.                       *//*********************** self documentation **********************//*****************************************************************************CONVOLUTION - Compute z = x convolved with yconv	compute the convolution of two input vector arrays******************************************************************************Input:lx		length of x arrayifx		sample index of first xx		array[lx] to be convolved with yly		length of y arrayify		sample index of first yy		array[ly] with which x is to be convolvedlz		length of z arrayifz		sample index of first zOutput:z		array[lz] containing x convolved with y******************************************************************************Function Prototype:void conv (int lx, int ifx, float *x, int ly, int ify, float *y,	int lz, int ifz, float *z);******************************************************************************Notes:The operation z = x convolved with y is defined to be           ifx+lx-1    z[i] =   sum    x[j]*y[i-j]  ;  i = ifz,...,ifz+lz-1            j=ifxThe x samples are contained in x[0], x[1], ..., x[lx-1]; likewise forthe y and z samples.  The sample indices of the first x, y, and z valuesdetermine the location of the origin for each array.  For example, ifz is to be a weighted average of the nearest 5 samples of y, one mightuse 	...	x[0] = x[1] = x[2] = x[3] = x[4] = 1.0/5.0;	conv(5,-2,x,lx,0,y,ly,0,z);	...In this example, the filter x is symmetric, with index of first sample = -2.This function is optimized for architectures that can simultaneously performa multiply, add, and one load from memory; e.g., the IBM RISC System/6000.Because, for each value of i, it accumulates the convolution sum z[i] in ascalar, this function is not likely to be optimal for vector architectures.******************************************************************************Author:  Dave Hale, Colorado School of Mines, 11/23/91*****************************************************************************//**************** end self doc ********************************/#include "cwp.h"/* prototype of function used internally */static void convs(int,int,float*,int,int,float*,int,int,float*);void conv (int lx, int ifx, float *x,	   int ly, int ify, float *y,	   int lz, int ifz, float *z)/*****************************************************************************Compute z = x convolved with y; i.e.,           ifx+lx-1    z[i] =   sum    x[j]*y[i-j]  ;  i = ifz,...,ifz+lz-1            j=ifx******************************************************************************Input:lx		length of x arrayifx		sample index of first xx		array[lx] to be convolved with yly		length of y arrayify		sample index of first yy		array[ly] with which x is to be convolvedlz		length of z arrayifz		sample index of first zOutput:z		array[lz] containing x convolved with y******************************************************************************Notes:The x samples are contained in x[0], x[1], ..., x[lx-1]; likewise forthe y and z samples.  The sample indices of the first x, y, and z valuesdetermine the location of the origin for each array.  For example, ifz is to be a weighted average of the nearest 5 samples of y, one mightuse 	...	x[0] = x[1] = x[2] = x[3] = x[4] = 1.0/5.0;	conv(5,-2,x,lx,0,y,ly,0,z);	...In this example, the filter x is symmetric, with index of first sample = -2.This function is optimized for architectures that can simultaneously performa multiply, add, and one load from memory; e.g., the IBM RISC System/6000.Because, for each value of i, it accumulates the convolution sum z[i] in ascalar, this function is not likely to be optimal for vector architectures.******************************************************************************Author:  Dave Hale, Colorado School of Mines, 11/23/91*****************************************************************************/#ifdef SIMPLE_CONV{	int ilx=ifx+lx-1,ily=ify+ly-1,ilz=ifz+lz-1,i,j,jlow,jhigh;	float sum;		x -= ifx;  y -= ify;  z -= ifz;	for (i=ifz; i<=ilz; ++i) {		jlow = i-ily;  if (jlow<ifx) jlow = ifx;		jhigh = i-ify;  if (jhigh>ilx) jhigh = ilx;		for (j=jlow,sum=0.0; j<=jhigh; ++j)			sum += x[j]*y[i-j];		z[i] = sum;	}}#else{	int ilx=ifx+lx-1,ily=ify+ly-1,ilz=ifz+lz-1,		i,j,ilow,ihigh,jlow,jhigh;	float sa,sb,xa,xb,ya,yb,*t;	/* if x is longer than y, swap x and y */	if (lx>ly) {		i = ifx;  ifx = ify;  ify = i;		i = ilx;  ilx = ily;  ily = i;		i = lx;  lx = ly;  ly = i;		t = x;  x = y;  y = t;	}		/* handle short x with special code */	if (lx>=1 && lx<=30) {		convs(lx,ifx,x,ly,ify,y,lz,ifz,z);		return;	}		/* adjust pointers for indices of first samples */	x -= ifx;	y -= ify;	z -= ifz;			/* OFF LEFT:  i < ify+ifx */		/* zero output for all i */	ilow = ifz;	ihigh = ify+ifx-1;  if (ihigh>ilz) ihigh = ilz;	for (i=ilow; i<=ihigh; ++i)		z[i] = 0.0;	/* ROLLING ON:  ify+ifx <= i < ify+ilx */		/* if necessary, do one i so that number of j in overlap is odd */	if (i<ify+ilx && i<=ilz) {		jlow = ifx;		jhigh = i-ify;		if ((jhigh-jlow)%2) {			sa = 0.0;			for (j=jlow; j<=jhigh; ++j)				sa += x[j]*y[i-j];			z[i++] = sa;		}	}		/* loop over pairs of i and j */	ilow = i;	ihigh = ilx+ify-1;  if (ihigh>ilz) ihigh = ilz;	jlow = ifx;	jhigh = ilow-ify;	for (i=ilow; i<ihigh; i+=2,jhigh+=2) {		sa = sb = 0.0;		xb = x[jhigh+1];		yb = 0.0;		for (j=jhigh; j>=jlow; j-=2) {			sa += xb*yb;			ya = y[i-j];			sb += xb*ya;			xa = x[j];			sa += xa*ya;			yb = y[i+1-j];			sb += xa*yb;			xb = x[j-1];		}		z[i] = sa;		z[i+1] = sb;	}		/* if number of i is odd */	if (i==ihigh) {		jlow = ifx;		jhigh = i-ify;		sa = 0.0;		for (j=jlow; j<=jhigh; ++j)			sa += x[j]*y[i-j];		z[i++] = sa;	}		/* MIDDLE:  ify+ilx <= i <= ily+ifx */		/* determine limits for i and j */	ilow = i;	ihigh = ily+ifx;  if (ihigh>ilz) ihigh = ilz;	jlow = ifx;	jhigh = ilx;		/* if number of j is even, do j in pairs with no leftover */	if ((jhigh-jlow)%2) {		for (i=ilow; i<ihigh; i+=2) {			sa = sb = 0.0;			yb = y[i+1-jlow];			xa = x[jlow];			for (j=jlow; j<jhigh; j+=2) {				sb += xa*yb;				ya = y[i-j];				sa += xa*ya;				xb = x[j+1];				sb += xb*ya;				yb = y[i-1-j];				sa += xb*yb;				xa = x[j+2];			}			z[i] = sa;			z[i+1] = sb;		}		/* else, number of j is odd, so do j in pairs with leftover */	} else {		for (i=ilow; i<ihigh; i+=2) {			sa = sb = 0.0;			yb = y[i+1-jlow];			xa = x[jlow];			for (j=jlow; j<jhigh; j+=2) {				sb += xa*yb;				ya = y[i-j];				sa += xa*ya;				xb = x[j+1];				sb += xb*ya;				yb = y[i-1-j];				sa += xb*yb;				xa = x[j+2];			}			z[i] = sa+x[jhigh]*y[i-jhigh];			z[i+1] = sb+x[jhigh]*y[i+1-jhigh];		}	}		/* if number of i is odd */	if (i==ihigh) {		sa = 0.0;		for (j=jlow; j<=jhigh; ++j)			sa += x[j]*y[i-j];		z[i++] = sa;	}	/* ROLLING OFF:  ily+ifx < i <= ily+ilx */		/* if necessary, do one i so that number of j in overlap is even */	if (i<=ily+ilx && i<=ilz) {		jlow = i-ily;		jhigh = ilx;		if (!((jhigh-jlow)%2)) {			sa = 0.0;			for (j=jlow; j<=jhigh; ++j)				sa += x[j]*y[i-j];			z[i++] = sa;		}	}		/* number of j is now even, so loop over both i and j in pairs */	ilow = i;	ihigh = ily+ilx;  if (ihigh>ilz) ihigh = ilz;	jlow = ilow-ily;	jhigh = ilx-2; /* Dave's new patch */        for (i=ilow; i<ihigh; i+=2,jlow+=2) {                sa = sb = 0.0;                xa = x[jlow];                yb = 0.0;                for (j=jlow; j<jhigh; j+=2) {                        sb += xa*yb;                        ya = y[i-j];                        sa += xa*ya;                        xb = x[j+1];                        sb += xb*ya;                        yb = y[i-1-j];                        sa += xb*yb;                        xa = x[j+2];                }                sb += xa*yb;                ya = y[i-j];                sa += xa*ya;                xb = x[j+1];                sb += xb*ya;                yb = y[i-1-j];                sa += xb*yb;                z[i] = sa;                z[i+1] = sb;        }		/* if number of i is odd */	if (i==ihigh) {		jlow = i-ily;		jhigh = ilx;		sa = 0.0;		for (j=jlow; j<=jhigh; ++j)			sa += x[j]*y[i-j];		z[i++] = sa;	}		/* OFF RIGHT:  ily+ilx < i */		/* zero output for all i */	ilow = i;	ihigh = ilz;	for (i=ilow; i<=ihigh; ++i)		z[i] = 0.0;}/* internal function optimized for short x */static void convs (int lx, int ifx, float *x,	   int ly, int ify, float *y, 	   int lz, int ifz, float *z){	int ilx=ifx+lx-1,ily=ify+ly-1,ilz=ifz+lz-1,		i,j,ilow,ihigh,jlow,jhigh;	float x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,		x10,x11,x12,x13,x14,x15,x16,x17,x18,x19,		x20,x21,x22,x23,x24,x25,x26,x27,x28,x29,		ya,yb,z0,z1,sum;		x -= ifx;	y -= ify;	z -= ifz;				/* OFF LEFT:  i < ifx+ify */	ilow = ifz;	ihigh = ify+ifx-1;  if (ihigh>ilz) ihigh = ilz;	for (i=ilow; i<=ihigh; ++i)		z[i] = 0.0;		/* ROLLING ON:  ify+ifx <= i < ify+ilx */	ilow = ify+ifx;  if (ilow<ifz) ilow = ifz;	ihigh = ify+ilx-1;  if (ihigh>ilz) ihigh = ilz;	jlow = ifx;	jhigh = ilow-ify;	for (i=ilow; i<=ihigh; ++i,++jhigh) {		for (j=jlow,sum=0.0; j<=jhigh; ++j)			sum += x[j]*y[i-j];		z[i] = sum;	}		/* MIDDLE:  ify+ilx <= i <= ily+ifx */	ilow = ify+ilx;  if (ilow<ifz) ilow = ifz;	ihigh = ily+ifx;  if (ihigh>ilz) ihigh = ilz;	if (lx==1) {		x0 = x[ifx];		for (i=ilow; i<=ihigh-1; i+=2) {			ya = y[i+1-ifx];  z1 = x0*ya;			yb = y[i-ifx];  z0 = x0*yb;			z[i+1] = z1;			z[i] = z0;		}	} else if (lx==2) {		x0 = x[ifx];		x1 = x[ifx+1];		for (i=ilow; i<=ihigh-1; i+=2) {			ya = y[i+1-ifx];  z1 = x0*ya;			yb = y[i-ifx];  z0 = x0*yb;  z1 += x1*yb;			ya = y[i-ifx-1];  z0 += x1*ya;			z[i+1] = z1;			z[i] = z0;		}	} else if (lx==3) {		x0 = x[ifx];		x1 = x[ifx+1];		x2 = x[ifx+2];		for (i=ilow; i<=ihigh-1; i+=2) {			ya = y[i+1-ifx];  z1 = x0*ya;			yb = y[i-ifx];  z0 = x0*yb;  z1 += x1*yb;			ya = y[i-ifx-1];  z0 += x1*ya;  z1 += x2*ya;			yb = y[i-ifx-2];  z0 += x2*yb;			z[i+1] = z1;			z[i] = z0;		}	} else if (lx==4) {		x0 = x[ifx];		x1 = x[ifx+1];		x2 = x[ifx+2];		x3 = x[ifx+3];		for (i=ilow; i<=ihigh-1; i+=2) {			ya = y[i+1-ifx];  z1 = x0*ya;			yb = y[i-ifx];  z0 = x0*yb;  z1 += x1*yb;			ya = y[i-ifx-1];  z0 += x1*ya;  z1 += x2*ya;			yb = y[i-ifx-2];  z0 += x2*yb;  z1 += x3*yb;			ya = y[i-ifx-3];  z0 += x3*ya;			z[i+1] = z1;			z[i] = z0;		}	} else if (lx==5) {		x0 = x[ifx];		x1 = x[ifx+1];		x2 = x[ifx+2];		x3 = x[ifx+3];		x4 = x[ifx+4];		for (i=ilow; i<=ihigh-1; i+=2) {			ya = y[i+1-ifx];  z1 = x0*ya;			yb = y[i-ifx];  z0 = x0*yb;  z1 += x1*yb;			ya = y[i-ifx-1];  z0 += x1*ya;  z1 += x2*ya;			yb = y[i-ifx-2];  z0 += x2*yb;  z1 += x3*yb;			ya = y[i-ifx-3];  z0 += x3*ya;  z1 += x4*ya;			yb = y[i-ifx-4];  z0 += x4*yb;			z[i+1] = z1;			z[i] = z0;		}	} else if (lx==6) {		x0 = x[ifx];		x1 = x[ifx+1];		x2 = x[ifx+2];		x3 = x[ifx+3];		x4 = x[ifx+4];		x5 = x[ifx+5];		for (i=ilow; i<=ihigh-1; i+=2) {			ya = y[i+1-ifx];  z1 = x0*ya;			yb = y[i-ifx];  z0 = x0*yb;  z1 += x1*yb;			ya = y[i-ifx-1];  z0 += x1*ya;  z1 += x2*ya;			yb = y[i-ifx-2];  z0 += x2*yb;  z1 += x3*yb;			ya = y[i-ifx-3];  z0 += x3*ya;  z1 += x4*ya;			yb = y[i-ifx-4];  z0 += x4*yb;  z1 += x5*yb;			ya = y[i-ifx-5];  z0 += x5*ya;			z[i+1] = z1;			z[i] = z0;		}	} else if (lx==7) {		x0 = x[ifx];		x1 = x[ifx+1];		x2 = x[ifx+2];		x3 = x[ifx+3];		x4 = x[ifx+4];		x5 = x[ifx+5];		x6 = x[ifx+6];		for (i=ilow; i<=ihigh-1; i+=2) {			ya = y[i+1-ifx];  z1 = x0*ya;			yb = y[i-ifx];  z0 = x0*yb;  z1 += x1*yb;			ya = y[i-ifx-1];  z0 += x1*ya;  z1 += x2*ya;			yb = y[i-ifx-2];  z0 += x2*yb;  z1 += x3*yb;			ya = y[i-ifx-3];  z0 += x3*ya;  z1 += x4*ya;			yb = y[i-ifx-4];  z0 += x4*yb;  z1 += x5*yb;			ya = y[i-ifx-5];  z0 += x5*ya;  z1 += x6*ya;			yb = y[i-ifx-6];  z0 += x6*yb;			z[i+1] = z1;			z[i] = z0;		}	} else if (lx==8) {		x0 = x[ifx];		x1 = x[ifx+1];		x2 = x[ifx+2];		x3 = x[ifx+3];		x4 = x[ifx+4];		x5 = x[ifx+5];		x6 = x[ifx+6];		x7 = x[ifx+7];		for (i=ilow; i<=ihigh-1; i+=2) {			ya = y[i+1-ifx];  z1 = x0*ya;			yb = y[i-ifx];  z0 = x0*yb;  z1 += x1*yb;			ya = y[i-ifx-1];  z0 += x1*ya;  z1 += x2*ya;			yb = y[i-ifx-2];  z0 += x2*yb;  z1 += x3*yb;			ya = y[i-ifx-3];  z0 += x3*ya;  z1 += x4*ya;			yb = y[i-ifx-4];  z0 += x4*yb;  z1 += x5*yb;			ya = y[i-ifx-5];  z0 += x5*ya;  z1 += x6*ya;			yb = y[i-ifx-6];  z0 += x6*yb;  z1 += x7*yb;			ya = y[i-ifx-7];  z0 += x7*ya;			z[i+1] = z1;			z[i] = z0;		}	} else if (lx==9) {		x0 = x[ifx];		x1 = x[ifx+1];		x2 = x[ifx+2];		x3 = x[ifx+3];		x4 = x[ifx+4];		x5 = x[ifx+5];		x6 = x[ifx+6];		x7 = x[ifx+7];		x8 = x[ifx+8];		for (i=ilow; i<=ihigh-1; i+=2) {			ya = y[i+1-ifx];  z1 = x0*ya;			yb = y[i-ifx];  z0 = x0*yb;  z1 += x1*yb;			ya = y[i-ifx-1];  z0 += x1*ya;  z1 += x2*ya;			yb = y[i-ifx-2];  z0 += x2*yb;  z1 += x3*yb;			ya = y[i-ifx-3];  z0 += x3*ya;  z1 += x4*ya;			yb = y[i-ifx-4];  z0 += x4*yb;  z1 += x5*yb;			ya = y[i-ifx-5];  z0 += x5*ya;  z1 += x6*ya;			yb = y[i-ifx-6];  z0 += x6*yb;  z1 += x7*yb;			ya = y[i-ifx-7];  z0 += x7*ya;  z1 += x8*ya;			yb = y[i-ifx-8];  z0 += x8*yb;			z[i+1] = z1;			z[i] = z0;		}	} else if (lx==10) {		x0 = x[ifx];		x1 = x[ifx+1];		x2 = x[ifx+2];		x3 = x[ifx+3];		x4 = x[ifx+4];		x5 = x[ifx+5];		x6 = x[ifx+6];		x7 = x[ifx+7];		x8 = x[ifx+8];		x9 = x[ifx+9];		for (i=ilow; i<=ihigh-1; i+=2) {			ya = y[i+1-ifx];  z1 = x0*ya;			yb = y[i-ifx];  z0 = x0*yb;  z1 += x1*yb;			ya = y[i-ifx-1];  z0 += x1*ya;  z1 += x2*ya;			yb = y[i-ifx-2];  z0 += x2*yb;  z1 += x3*yb;			ya = y[i-ifx-3];  z0 += x3*ya;  z1 += x4*ya;			yb = y[i-ifx-4];  z0 += x4*yb;  z1 += x5*yb;			ya = y[i-ifx-5];  z0 += x5*ya;  z1 += x6*ya;			yb = y[i-ifx-6];  z0 += x6*yb;  z1 += x7*yb;			ya = y[i-ifx-7];  z0 += x7*ya;  z1 += x8*ya;			yb = y[i-ifx-8];  z0 += x8*yb;  z1 += x9*yb;			ya = y[i-ifx-9];  z0 += x9*ya;			z[i+1] = z1;			z[i] = z0;

⌨️ 快捷键说明

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