【发布时间】:2019-02-18 11:30:11
【问题描述】:
我正在编写一个接收时变信号并返回 FFT 的函数。它遵循 Matlab 文档:
- https://www.mathworks.com/help/matlab/math/fourier-transforms.html
- https://www.mathworks.com/help/matlab/ref/fftshift.html
它适用于非常简单的正弦曲线总和。
对于其他模拟信号,例如阶跃函数,我最终得到了一些 fubar,它以类似锯齿的方式振荡。这是一个使用重载阶跃函数的最小示例,它绘制了 FFT 权重的虚部:
%Create and plot sign function
Fs = 1000;
dt = 1/Fs;
tvals = -1: dt: 1-dt;
yvals = sign(tvals); %don't use heaviside() it is very slow
subplot(2,1,1);
plot(tvals, yvals, 'k', 'LineWidth', 2); hold on;
axis([-1 1 -1.1 1.1]);
%Calculate center-shifted FFT and plot imaginary part
fftInitial = fft(yvals);
n = length(fftInitial);
dF = Fs/n;
frequenciesShifted = -Fs/2: dF: Fs/2-dF; %zero-centered frequency range
fftShifted = fftshift(fftInitial/length(yvals));
subplot(2,1,2);
plot(frequenciesShifted, imag(fftShifted), 'b', 'LineWidth', 2);hold on
xlim([-8 8])
请注意,已知的虚构解决方案是 2/jw 或 j(-2/w)。
请注意,除了锯齿,这是我最关心的问题,这些权重的 包络 似乎并没有遵循这一点。它实际上似乎围绕原点翻转。不知道我在这里做错了什么组合。
根据一些有用的反馈,人们指出了这个问题:
Analytical Fourier transform vs FFT of functions in Matlab
特别是,在时间数组中不包含零可能会导致问题,这是那里的主要问题。我的代码中的时间数组包含一个零,所以它看起来不像是重复的。我通过时移步骤将我的零推到了数组的前面(尽管坦率地说,我已经做了很多 fft() 没有这样做,而且它们看起来都很好,所以我不认为这是问题所在,但是我现在只想将其作为一个问题删除)。所以我们最终得到:
Fs = 1000;
dt = 1/Fs;
tvals = 0: dt: 2-dt;
yvals = sign(tvals-1); %don't use heaviside() it is very slow
zeroInd = find(yvals == 1, 1, 'first');
yvals(zeroInd-1) =0;
%Calculate center-shifted FFT and plot imaginary part
fftInitial = fft(yvals);
n = length(fftInitial);
dF = Fs/n;
frequenciesShifted = -Fs/2: dF: Fs/2-dF; %zero-centered frequency range
fftShifted = fftshift(fftInitial/length(yvals));
%Plot stuff
subplot(2,1,1);
plot(tvals, yvals, 'k', 'LineWidth', 2); hold on;
axis([0 2 -1.1 1.1]);
subplot(2,1,2);
plot(frequenciesShifted, imag(fftShifted), 'b', 'LineWidth', 2);hold on
xlim([-8 8])
grid on;
我仍然得到相同的曲折功能和相同的错误信封。所以,虽然我确实看到我的问题和那个问题密切相关,但我不确定它们是否重复。而且我真的很想能够画出这些组件的值的中途合理的外观图(我确实处理了一些基本上是阶跃函数的生理信号(与我的相比,它们移动非常快)测量仪器,所以这对我来说不仅仅是一个学术练习)。
【问题讨论】:
-
重复问题使用不同的函数,但与您面临的问题完全相同:FFT 假定原点 (t=0) 是输入数组中的第一个元素。您正在计算移位阶跃函数的 FFT。
-
这个问题并不是真正的重复:首先,我的时间表示为零,这就是他们帖子中的问题。其次,我的主要问题是 FT 的振荡行为,而不是镜面反射,如我的标题所示。但我会编辑我的 Q 以提及该帖子。
-
@CrisLuengo Cris 我读过它:......正如你在那里写的那样“FFT 期望原点位于第一个(最左边)样本。这就是 ifftshift 的用途:”所以我做了什么在我修改后的问题中,我的第一个时间点是 0。我认为这将消除对iffshift的需要。现在将更仔细地研究这一点。
-
@CrisLuengo 为什么这个极其简单的解决方案适用于单位脉冲函数(无需花费时间等),具有华丽的情节,但是当我用一个单一的做完全相同的事情时阶跃函数,是灾难吗? stackoverflow.com/questions/19717779/… 那就是为什么那里的答案如此简单易行。我只是没有看到区别(特别是考虑到一个脉冲只是两个符号的总和!)。
-
我错了,你有这个问题,还有第二个问题。对不起。看我的回答。您在此处链接的单位脉冲问题绘制了傅立叶变换的幅度,因此看不到信号的变化。