python 中 sinc 函数的傅立叶变换

问题描述 投票:0回答:1

我想知道如何绘制正弦函数的傅立叶变换。从理论上讲,我希望看到一个矩形函数或看起来像高帽函数的东西。我使用 numpy 的 linspace 定义了一组“x”点,并为每个 x 值相应地计算了 np.sinc。然后我可以轻松地绘制它来展示以 x=0 为中心的简单正弦函数。

然后我使用 scipy.fftpack.fft 计算 sinc 值数组的傅立叶变换,并尝试绘制这些结果,期望看到矩形或顶帽函数。相反,我得到了如下所示的图:

sinc function and its Fourier transform plots

我不确定为什么会发生这种情况以及我可以采取什么措施来解决它。如有任何帮助,我们将不胜感激。

python fft
1个回答
0
投票

有点晚了,但无论如何,这里有一个答案:

是的,从理论上讲你会期望看到一个矩形函数。然而,

fft
的输出在几个方面与原始(连续)傅里叶变换不同,另请参阅文档(NumPy,但据我所知,算法与
scipy.fftpack.fft
相同),所以您需要采取一些额外的步骤才能获得预期的输出。

首先,一些代码(大约)重现您的绘图:

import numpy as np
import matplotlib.pyplot as plt
from math import pi

# Define a time axis, plus some parameters for later use
N = 500
t_start, t_end = -12.5, 12.5

dt = (t_end - t_start)/N
fs = 1/dt # sampling frequency
fN = fs/2 # Nyquist frequency

t = np.linspace(t_start, t_end, N, endpoint = False)

# The sinc function (note that NumPy uses the normalised sinc,
# defined as sin(pi*t)/(pi*t))
f = np.sinc(t)

plt.figure()
plt.plot(t, f)

# The FFT
F = np.fft.fft(f)

plt.figure()
plt.plot(np.real(F))
# Not sure how you produced your fft plot; just plotting F issues a warning
# and discards the complex part of F, resulting in the same plot as above.

问题1:输出偏移

引用 NumPy FFT 文档:结果中的值遵循所谓的“标准”顺序:如果

A = fft(a, n)
,则
A[0]
包含零频率项(信号之和),它始终是纯实数为真实输入。然后
A[1:n/2]
包含正频率项,
A[n/2+1:]
包含负频率项,按负频率递减的顺序排列。对于偶数个输入点,
A[n/2]
表示正奈奎斯特频率和负奈奎斯特频率,并且对于实数输入也是纯实数。对于奇数个输入点,
A[(n-1)/2]
包含最大的正频率,而
A[(n+1)/2]
包含最大的负频率。例程
np.fft.fftfreq(n)
返回一个数组,给出输出中相应元素的频率。例程
np.fft.fftshift(A)
会移动变换及其频率,将零频率分量放在中间,并且
np.fft.ifftshift(A)
会撤消该移动。

不,离散傅立叶变换并不真正包含负频率,但以这种方式思考它对于与连续版本进行比较是很好的(并且完全可以接受,因为 DFT 是周期性的)。

# use fftshift to centre output at zero frequency
F_shifted = np.fft.fftshift(F)
# use fftfreq to get frequency axis
freq = np.fft.fftfreq(N, dt)
freq_shifted = np.fft.fftshift(freq)

plt.figure()
plt.plot(freq_shifted, np.real(F_shifted))

问题2:输出振荡

感谢 @Chris Luengo 的解释:这是因为

fft
期望一个周期性输入信号,其原点 (t = 0) 在第一个元素中。将原点放在中间,即
N/2
处,将给出延迟 sinc 的傅里叶变换,该傅里叶变换相对于 sinc 的傅里叶变换有相移(即乘以复指数;移位定理)。在 DFT 情况下,这表现为在奈奎斯特频率下的复指数振荡(参见例如Wikipedia)。该复指数的大小为 1(频谱中的能量不变),因此如果您绘制输出的绝对值,则不会出现任何振荡。然而,正确的解决方案是移动输入信号,使其起源于第一个元素。

# Plot absolute value of F_shifted, oscillations will have disappeared
plt.figure()
plt.plot(freq_shifted, abs(F_shifted))

# Shift input signal before applying fft
f_shifted = np.fft.ifftshift(f)
# Determine FFT and shift output
F = np.fft.fftshift(np.fft.fft(f_shifted))

plt.figure()
plt.plot(freq_shifted, np.real(F))

问题3:输出幅度关闭

参见问题1下的解释;

fft
的输出按输入信号之和缩放。

# Scale output
tot = sum(f)
F_scaled = 1/tot*F

plt.figure()
plt.plot(freq_shifted, np.real(F_scaled))

最后,输出“角”周围保留的振荡是 rect 函数在那里不连续的结果。为了正确捕获这些不连续性,您需要无限数量的频率。

fft
算法仅包括高达奈奎斯特频率的频率,因此会出现振荡(称为吉布斯现象)。

© www.soinside.com 2019 - 2024. All rights reserved.