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);

结果

%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

结果

  • 15
    点赞
  • 114
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

国服最强貂蝉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值