MATLAB线性卷积圆周卷积FFT程序

%编制一个计算两个序列线性卷积的通用程序,计算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);

结果

MATLAB线性卷积圆周卷积FFT程序_第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

结果

MATLAB线性卷积圆周卷积FFT程序_第2张图片

MATLAB线性卷积圆周卷积FFT程序_第3张图片

MATLAB线性卷积圆周卷积FFT程序_第4张图片

你可能感兴趣的:(MATLAB,MATLAB,数字信号处理,线性卷积,圆周卷积,FFT)