为了大家能够复现各个图中的结果,我附上了所有我编写的MATLAB代码。
创作不易,未经允许,禁止转载。
另外,说明一下,用MATLAB做FFT并不要求数据点个数必须为以2为基数的整数次方。之所以很多资料上说控制数据点数为以2为基数的整数次方,是因为这样就能采用以2为基的FFT算法,提升运算性能。
如果数据点数不是以2为基数的整数次方,处理方法有两种,一种是在原始数据开头或末尾补零,即将数据补到以2为基数的整数次方,这是“补零”的一个用处;第二种是采用以任意数为基数的FFT算法。
而MATLAB的
函数在参数
正好就是数据
的长度,但又不是以2为基数的整数次方时,并不会采用补零的方法,而是采用以任意数为基数的FFT算法,这样也能得到很好的结果,只不过速度要稍稍慢了一些,但一般的计算量是体现不出来的。
快速傅里叶变换 FFT
比如,现在我有一个信号,这个信号中仅包含两个正(余)弦波,一个是
,一个是
,即
。设定采样频率为
,如果采
个点,那么时域信号的时长就有
。
如果,直接对这1000个数据点其做快速傅里叶变换,将得到频谱图:
可以发现,频谱点稀疏,在1MHz附近根本无法将1 MHz 和1.05 MHz 的两个频率分开。
clear;clc
close all
%% FFT
Fs = 100e6; % 采样频率 Hz
T = 1/Fs; % 采样周期 s
L0 = 1000; % 信号长度
L = 1000; % 数据长度
t0 = (0:L0-1)*T; % 信号时间序列
x = cos(2*pi*1e6*t0) + cos(2*pi*1.05e6*t0); % 信号函数
t = (0:L-1)*T; % 数据时间序列
%% Plot
figure(1)
plot(t*1e6,x,'b-','linewidth',1.5)
title ('fontsize{10}fontname{Times New Roman}Time domain signal')
xlabel('fontsize{10}fontname{Times New Roman}it t /rm mus')
ylabel('fontsize{10}fontname{Times New Roman}it yrm(ittrm)')
grid on;
axis([0 10 -2 2])
set(gca,'FontSize', 10 ,'FontName', 'Times New Roman')
set(gcf,'unit','centimeters','position',[15 10 13.53 9.03],'color','white')
%% FFT
Y = fft(x); % 快速傅里叶变换
% 计算双侧频谱 P2。然后基于 P2 和偶数信