/* */
#include
/*相关卷积函数的声明,具体用法请参照后文*/
void linear_conv(int *, int *, int *, int , int);//计算线性卷积函数 void circular_conv( int *, int * , int *, int );//计算圆周卷积函数
void seg_retain_conv(int *, int *, int*, int, int);//利用分段保留法计算卷积
void main() {
if( NULL == ( x=(int *)malloc( Lx*sizeof(int) ) ) )//为x[]申请内存空间 { }
if( NULL == ( h=(int *)malloc( N*sizeof(int) ) ) ) { }
printf(\exit(1); printf(\exit(1);
//申请内存失败,退出
printf(\请输入h[]的长度M=\scanf_s(\
printf(\请输入x[]的长度Lx=\
scanf_s(\//在VC6.0中使用scanf(\
printf(\printf(\提示\
printf(\所输入的M值不要超过N的值,此程序默认的N值为128\\n\
printf(\int *x=NULL; int *h=NULL; int Lx,M,i; int *y=NULL; clock_t t1,t2;
//clock_t为长整型数据,可以进入time.h中查询
功能:实现利用分段保留法计算卷积,和直接线性卷积,两者在大数据点时的运算时间对比。
一样
if( NULL == ( y=(int *)malloc( (Lx+M-1)*sizeof(int) ) ) ) { }
srand((unsigned int)time(0));//播种子,调用此函数的目的是为了在每次运行时随机函数生成的数值都不//生成数组x[] printf(\数组x[]:\\n\for( i=0; i //生成数组h[] printf(\数组h[]:\\n\for( i=0; i printf(\ printf(\分段卷积后的结果------------------------------\\n\\n\t1=clock(); //记录起始时间,clock()函数在time.h中 seg_retain_conv(x,h,y,Lx,M); t2=clock(); //记录最后的时间 for( i=0; i printf(\采用分段保留法进行圆周卷积所用时间:%ld ms\ printf(\printf(\线性卷积后的结果-------------------------------\\n\\n\ printf(\ if(i { } h[i]=0; //不足的点数通过补零补齐N点 h[i]=(int)rand()%5; //前M个点为h[M]的信号值,赋予0~5之间的随机数 x[i]=(int)rand()%5; printf(\ //调用随机函数生成x[],随机数的范围为0~5 printf(\exit(1); printf(\ } /* */ void linear_conv(int *x, int *h ,int *y,int L, int M) { } /* 计算圆周卷积函数, 其中x[],h[],y[]分别为输入信号、冲击响应和输出信号, len为圆周卷积的长度也就是周期卷积的周期。 int i,j; int n; n=L+M-1; for( i=0; i y[i]=0; for( j=0; j if(j<=i && (i-j) y[i]+=x[j]*h[i-j]; 线性卷积函数,x[]为输入信号,h[]为系统冲击响应,y[]为输出结果 , L、M分别为x[]、h[]的长度 free(x);//释放x[]所占的内存空间 free(h); free(y); t1=clock(); linear_conv(x,h,y,Lx,M); t2=clock(); for( i=0; i printf(\线性卷积所用时间:%ld ms\ printf(\ printf(\ */ 在使用该函数之前需对x[],h[]进行补零使他们的长度都为len void circular_conv( int *x, int *h , int *y, int len) { } /* */ void seg_retain_conv( int *x, int *h, int *y, int Lx, int M) { //利用重叠保留法对x[]进行分段 count=0; for( j=0; j if( j buffer[0][j] = 0; L=N-M+1;//每段的长度为L n=((Lx+M-1)%L==0)?(Lx+M-1)/L:((Lx+M-1)/L+1);//总的段数 int i,j,n,L,count; int y_buffer[N]; //用来存储圆周卷积输出的数据 int buffer[512][N]; //如果要增加运算的点数可以将buffer[512][N]数据改大点,比如buffer[600][N] 分段保留法进行圆周卷积函数,其中x[],h[],y[]分别为输入信号、冲击响应和输出序列, Lx,M分别为x[],h[]的长度 int i,j; for( i=0; i y[i]=0; for( j=0; j if(i-j<0) { }else if(i-j>=0) { } y[i]+=x[j]*h[i-j]; y[i]+=x[j]*h[i-j+len]; } { } if( count buffer[0][j]=0; buffer[0][j] = x[count];//buffer[0]后L个数据赋上x[]的第一个子序列的数据 count++; //此语句不能省略,若省略了当x[]就分为1段时会出错 for( i=1 ; i //利用圆周卷积函数进行分段卷积 count=0; for( i=0; i circular_conv(buffer[i],h,y_buffer,N); for( j=0; j if(j>M-2) // { if(count y[count]=y_buffer[j]; 将前M-1个数据删去不输出 for( j=0; j if( j if( count buffer[i][j]=0; buffer[i][j]=x[count]; //每个子序列的后L个数赋上对应x[]的一个子段数据 count++; buffer[i][j]=buffer[i-1][j+L]; //每个子序列的前边补上上一子序列的后M-1个值 } } } } } count++;