【问题标题】:Analytical Fourier transform vs FFT of functions in MatlabMatlab中函数的解析傅里叶变换与FFT
【发布时间】:2018-03-16 09:59:24
【问题描述】:

我已经针对这个问题修改了Comparing FFT of Function to Analytical FT Solution in Matlab 中的代码。我正在尝试进行 FFT 并将结果与​​ Wikipedia tables 中的分析表达式进行比较。

我的代码是:

a = 1.223;
fs = 1e5; %sampling frequency
dt = 1/fs;
t = 0:dt:30-dt;     %time vector
L = length(t); % no. sample points
t = t - 0.5*max(t); %center around t=0

y = ; % original function in time
Y = dt*fftshift(abs(fft(y))); %numerical soln

freq = (-L/2:L/2-1)*fs/L; %freq vector
w = 2*pi*freq; % angular freq

F = ; %analytical solution

figure; subplot(1,2,1); hold on
plot(w,real(Y),'.')
plot(w,real(F),'-')
xlabel('Frequency, w')
title('real')
legend('numerical','analytic')
xlim([-5,5])
subplot(1,2,2); hold on;
plot(w,imag(Y),'.')
plot(w,imag(F),'-')
xlabel('Frequency, w')
title('imag')
legend('numerical','analytic')
xlim([-5,5])

如果我研究高斯函数并让

y = exp(-a*t.^2); % original function in time

F = exp(-w.^2/(4*a))*sqrt(pi/a); %analytical solution

在上面的代码中,当绘制函数的实部和虚部时,看起来有很好的一致性:

但如果我研究一个衰减指数乘以 Heaviside 函数:

H = @(x)1*(x>0); % Heaviside function
y = exp(-a*t).*H(t);

F = 1./(a+1j*w); %analytical solution

然后

为什么会有差异?我怀疑它与Y = 行有关,但我不确定为什么或如何。

编辑:我将Y = dt*fftshift(abs(fft(y))); 中的ifftshift 更改为fftshift。然后我还删除了abs。第二张图现在看起来像:

“镜像”图背后的数学原因是什么?如何删除它?

【问题讨论】:

  • 傅里叶变换虽然密切相关,但不是离散傅里叶变换(通过 FFT 算法实现)。因此,在某些特定条件下,您可能会获得非常接近的结果,但通常您会得到明显的差异(正如您所观察到的)
  • 另外,通过采用abs,您消除了虚部,所以它始终为0。我认为您需要fftshift 而不是ìfftshift
  • @Zep 这只是一个 MWE - 最终我需要对没有分析形式的更复杂的函数进行 FFT 和 IFFT。所以我正在做类似FFT{ IFFT[F(w)]*IFFT[G(w)] / IFFT[J(w)] } 的事情,我只知道F,G,J 的频率向量。
  • @Medulla Oblongata 我删除了我的评论,因为我认为 ifftshift 会移动和逆变换,而不是只会移动。
  • 我猜第一个实验,使用高斯,是因为abs 调用?它删除了计算错误的相位分量。在第二个图中,您可以看到abs 的效果:没有虚部,纯正实部。当您删除第三个图中的abs 时,您会看到相位完全错误,但幅度是正确的。

标签: matlab fft


【解决方案1】:

问题底部的图未镜像。如果您使用线而不是点来绘制它们,您会看到数字结果具有非常高的频率。绝对分量匹配,但相位不匹配。发生这种情况时,几乎可以肯定是时域发生了变化。

确实,您定义了时域函数,原点位于中间。 FFT 期望原点位于第一个(最左侧)样本。这就是ifftshift 的用途:

Y = dt*fftshift(fft(ifftshift(y)));

ifftshift 将原点移动到第一个样本,为fft 调用做准备,fftshift 将结果的原点移动到中间,以便显示。


编辑

您的t 没有 0:

>> t(L/2+(-1:2))
ans =
  -1.5000e-05  -5.0000e-06   5.0000e-06   1.5000e-05

t(floor(L/2)+1) 处的样本需要为 0。即ifftshift 移动到最左边的样本。 (我在那里使用floor 以防L 的大小是奇数,而不是这里的情况。)

要生成正确的t,请执行以下操作:

fs = 1e5; % sampling frequency
L = 30 * fs;
t = -floor(L/2):floor((L-1)/2);
t = t / fs;

我首先生成一个整数t 轴的正确长度,0 在正确的位置(t(floor(L/2)+1)==0)。然后我通过除以采样频率将其转换为秒。

有了这个t,上面我建议的Y,以及你的其余代码,我看到这个高斯示例:

>> max(abs(F-Y))
ans =    4.5254e-16

对于其他功能,我看到更大的差异,大约为 6e-6。这是由于无法对 Heaviside 函数进行采样。您的采样函数需要 t=0,但 H 在 0 处没有值。我注意到实分量具有相似幅度的偏移,这是由 t=0 处的样本引起的。

通常是the sampled Heaviside function is set to 0.5 for t=0。如果我这样做,偏移量将被完全消除,实际分量的最大差异减少 3 个数量级(最大误差发生在非常接近 0 的值上,我看到的是锯齿形图案)。对于虚部,最大误差降低到 3e-6,仍然相当大,在高频时最大。我将这些错误归因于理想和采样的 Heaviside 函数之间的差异。

您可能应该将自己限制在带限函数(或近带限函数,例如高斯函数)。您可能想尝试用带有小 sigma 的误差函数(高斯的积分)替换 Heaviside 函数(sigma = 0.8 * fs 是我认为正确采样的最小 sigma)。 Its Fourier transform is known.

【讨论】:

  • 您对ifftshift 的看法是正确的,现在情节看起来还不错。但是当我用高斯函数测试这行代码时,FFT 也给出了 10^(-6) 量级的小虚部。为什么会出现,有没有办法删除它?
  • @MedullaOblongata:我猜是数字不准确。或者,这可能是输入函数计算中的一个非常小的变化。您的时间轴样本中是否有实际的t==0?使用dt 增量计算t 会引入错误,而t-0.5*max(t) 可能也不精确。尝试用整数创建一个t 向量,然后除以fs。确保t(floor(L/2)+1)==0.
  • 冒号运算符和linspace的区别请看这里:stackoverflow.com/q/26292695/7328782
  • @MedullaOblongata:我已经用正确的形式更新了答案以构建时间轴t
猜你喜欢
  • 1970-01-01
  • 2021-07-12
  • 2012-08-21
  • 2012-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多