MATLAB中fft函数的正确使用方法
问题来源:在阅读莱昂斯的《数字信号处理》第三章离散傅里叶变换时,试图验证实数偶对称信号的傅里叶变换实部为偶对称的且虚部为零。验证失败。验证信号为矩形信号,结果显示虚部是不为零且最大幅值等于信号幅值。
错误原因:MATLAB中的fft函数默认其 N 点输入信号的时间序号为从 0 到 N-1 ,默认其输出信号的频率序号为从 0 到 N-1 。而当试图输入一个时间序号为从 -N/2 到 N/2-1 ( N 为偶数时)或从 -(N-1)/2 到 (N-1)/2 ( N 为奇数)的信号时,输出将会产生相移,看到的频谱的实部、虚部和相位都不是原始信号的 fft 的结果。只有频谱的幅值等于原始信号的 fft 的结果。
解决方法:在进行 fft 之前须使用 ifftshift 函数对原始信号进行移位,整个正确的 fft 过程为 fft(ifftshift(signal)) 。然而这样计算得到的 fft 也需要在频域使用 fftshift 进行移位才能显示频率序号为从 -N/2 到 N/2-1 ( N 为偶数时)或从 -(N-1)/2 到 (N-1)/2 ( N 为奇数)的频谱,即 fftshift(fft(ifftshift(signal))) 。在对频率序号为从 -(N+1)/2 到 (N+1)/2 的信号进行 ifft 的时候也会有类似的问题,解决方式为 fftshift(ifft(ifftshift(spectrum))) 。
注意:当 N 为奇数,若要使用 ifftshift 构造偶对称信号,须按照时间序号为从 -N/2 到 N/2-1 构造。即构造 [ 1 2 3 4 5 4 3 2 ] 经过ifftshift之后变为 [ 5 4 3 2 1 2 3 4 ] ,原信号中位于 0 时间序号的“5”依然在 0 时间序号的位置。
参考资料
1. FFT of a real symmtric vector is not real and symmetric
http://stackoverflow.com/questions/25042379/fft-of-a-real-symmetric-vector-is-not-real-and-symmetric#
2. Correct use of fftshift and ifftshift at input to fft and ifft
http://www.mathworks.com/matlabcentral/newsreader/view_thread/285244