%编制一个计算两个序列线性卷积的通用程序,计算x(n)*h(n)
%编制一个计算循环卷积的通用程序,计算 4 种情况下两个序列的循环卷积
%用到的函数:circonv.m cirshiftd.m
%% 两个序列
clear all;
close all;
X=[1 2 3 4 5]; %生成 x(n)
h=[1 2 1 2]; %生成 h(n)
%% 用函数 conv 计算线性卷积
y1=conv(X,h);
ny1=[0:1:length(y1)-1];
N=5; %X长度
M=4; %h长度
L=M+N-1; %卷积长度
nx=0:N-1;
nh=0:M-1;
ny=0:L-1; %横轴长度
%% 用函数 circonv 计算线性卷积
N0=5; %卷积点数
N1=6;
N2=9;
N3=10;
y2=circonv(X,h,N0); %用函数 circonv 计算 N0 点循环卷积
ny2=[0:1:length(y2)-1];
y3=circonv(X,h,N1); %用函数 circonv 计算 N1 点循环卷积
ny3=[0:1:length(y3)-1];
y4=circonv(X,h,N2); %用函数 circonv 计算 N1 点循环卷积
ny4=[0:1:length(y4)-1];
y5=circonv(X,h,N3); %用函数 circonv 计算 N1 点循环卷积
ny5=[0:1:length(y5)-1];
%% 图像表示
%x(n)图像
subplot(2,4,1);
stem(nx,X,'.k');%X的冲激用黑色表示
xlabel('n');
ylabel('x(n)');
grid on; %打开网格
%h(n)图像
subplot(2,4,2);
stem(nh,h,'.k');
xlabel('n');
ylabel('h(n)');
grid on;
%线性卷积
subplot(2,4,3);
stem(ny,y1,'.k');
xlabel('n');
ylabel('y1(n)');
grid on;
%圆周卷积
subplot(2,4,5);
stem(ny2,y2,'.k');
xlabel('n');
ylabel('y2(n)');
grid on;
subplot(2,4,6);
stem(ny3,y3,'.k');
xlabel('n');
ylabel('y3(n)');
grid on;
subplot(2,4,7);
stem(ny4,y4,'.k');
xlabel('n');
ylabel('y4(n)');
grid on;
subplot(2,4,8);
stem(ny5,y5,'.k');
xlabel('n');
ylabel('y5(n)');
grid on;
%直接计算圆周卷积y=circonv(x1,x2,N)
function yc=circonv(x1,x2,N)
%y:output sequences
%x1,x2:input sequences
%N:circulation length
if length(x1)>N
error( 'N must not be less than length of x1 ');
end
if length(x2)>N
error( 'N must not be less than length of x2 ');
end
%以上语句判断两个序列的长度是否小于 N
x1=[x1,zeros(1,N-length(x1))];
%填充序列x1(n)使其长度为N1+N2-1(序列%h(n)的长度为 N1,序列 x(n)的长度为 N2)
x2=[x2,zeros(1,N-length(x2))];
%填充序列 x2(n)使其长度为 N1+N2-1
n=[0:1:N-1];
x2=x2(mod(-n,N)+1); %取模 生成序列x2((-n))N
H=zeros(N,N);
for n=1:1:N
H(n,:)=cirshiftd(x2,n-1,N); %该矩阵的k行为x2((k-1-n))N
end
yc=x1*H'; %矩阵的方法计算循环卷积
%形成矩阵
function y=cirshiftd(x,m,N)
%直接实现序列x的循环移位
%y=cirshiftd(x,m,N);
%x:长度小于N的输入序列
%m:转移多少
%N:圆形长度
%y:输出移位序列
if length(x)>N
error('length of x must be less than N');
end
x=[x,zeros(1,N-length(x))];
n=[0:1:N-1];
y=x(mod(n-m,N)+1);
结果
%FFT实现快速卷积
%用到的函数 f_FFT.m
%% 主程序
clear all;
close all;
N1=[0:1:15]; %N1=16
N2=[0:1:16]; %N2=17
xn1=ones(1,16);
xn2=cos(2*N1*pi/16);
xn3=(1/3).^N1;
hn=(1/2).^N2;
y1=f_FFT(xn1,hn);
y2=f_FFT(xn2,hn);
y3=f_FFT(xn3,hn);
%函数
function y = f_FFT(xn,hn)
N1=length(xn);
N2=length(hn);
N=N1+N2-1;
XK=fft(xn,N); %离散傅立叶变换快速算法
HK=fft(hn,N);
YK=XK.*HK;
y=ifft(YK,N); %离散傅立叶反变换快速算法
if all (imag(xn)==0)&(all(imag(hn)==0))
%实序列的循环卷积仍然为实序列
y=real(y); %复数的实部
x=0:N-1;
figure;
stem(x,y,'.k');
end
结果