python - 为什么 numpy 的 fft 的每一个第二个系数都是其应有的倒数?

标签 python numpy fft

这就是我尝试使用 numpy 获取单位脉冲的 DFT 的方法(该图显示了单位脉冲):

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np

def plot_complex(space, arr):
    plt.figure()
    plt.plot(space, arr.real, label="real")
    plt.plot(space, arr.imag, label="imag")
    plt.legend(loc='upper left')

f = lambda x: 1 if abs(x) < 0.5 else 0
lo = -10
hi = 10
num_samples = 1000
sample_freq = num_samples/(hi-lo)
linspace = np.linspace(lo, hi, num_samples)
array = np.vectorize(f)(linspace)

coeff = np.fft.fft(array, num_samples)

# we need to shift the coefficients because otherwise negative frequencies are in the right half of the array
coeff_shifted = np.fft.fftshift(coeff)

plot_complex(linspace, array)
plt.title("The unit pulse")

Unit pulse plot

这似乎有效,因为使用逆 fft 可以恢复原始单位脉冲:

icoeff = np.fft.ifft(coeff)

plot_complex(linspace, icoeff)
plt.title("The recovered signal")

Recovered pulse plot

但是,当查看信号时,它看起来不像我在连续傅里叶变换中期望的 sinc 函数:

freqspace = np.vectorize(lambda x: x * sample_freq)(np.fft.fftshift(np.fft.fftfreq(1000)))
plot_complex(freqspace, coeff_shifted)
plt.title("DFT coefficients")

plot_complex(freqspace[450:550], coeff_shifted[450:550])
plt.title("Zoomed in")

Plot of the coefficients

Zoomed in plot

只有当每个第二个系数乘以 -1 时,它才看起来像 sinc 函数:

# multiplies every second number in the array by -1
def flip_seconds(coeff):
    return np.array([(1 if i%2 == 0 else -1) * s for (i,s) in enumerate(coeff)])

plot_complex(freqspace, flip_seconds(coeff_shifted))

Plot of the altered coefficients

这是为什么?

最佳答案

这有点麻烦,也许其他人想用数学来冲洗它:)但基本上你已经将你的“脉冲域”窗口设置为 [-X/2, X/2],而 fft 期望它被窗口化 [0, X]。差异在于“脉冲域”的偏移,从而导致频域的相移。因为您已经移动了正好一半的窗口,所以相移恰好是 exp(-pi * f * i/Sample_freq) (或类似的东西),因此它显示为所有其他项相乘如exp(-pi * i)。您可以通过在应用 fft 之前移动“脉冲空间”来解决此问题。

import matplotlib.pyplot as plt
import numpy as np

def plot_complex(space, arr):
    plt.figure()
    plt.plot(space, arr.real, label="real")
    plt.plot(space, arr.imag, label="imag")
    plt.legend(loc='upper left')

lo = -10
hi = 10
num_samples = 1000
sample_freq = num_samples/(hi-lo)
linspace = np.linspace(lo, hi, num_samples)
array = abs(linspace) < .5
array_shifted = np.fft.fftshift(array)

coeff = np.fft.fft(array_shifted, num_samples)

# we need to shift the coefficients because otherwise negative frequencies are in the right half of the array
coeff_shifted = np.fft.fftshift(coeff)

plot_complex(linspace, array_shifted)
plt.title("The unit pulse (shifted)")

icoeff = np.ftt.ifftshift(np.fft.ifft(coeff))

plot_complex(linspace, icoeff)
plt.title("The recovered signal")

freqspace = np.fft.fftshift(np.fft.fftfreq(1000)) * sample_freq
plot_complex(freqspace, coeff_shifted)
plt.title("DFT coefficients")

plot_complex(freqspace[450:550], coeff_shifted[450:550])
plt.title("Zoomed in")


def flip_seconds(coeff):
    return np.array([(1 if i%2 == 0 else -1) * s for (i,s) in enumerate(coeff)])

plot_complex(freqspace, flip_seconds(coeff_shifted))
plt.show()

关于python - 为什么 numpy 的 fft 的每一个第二个系数都是其应有的倒数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51645045/

相关文章:

python - 在数组的 numpy 数组中找到 n 个最小的项目

python - 如何在 Python 中安装 blaze 模块(Continuum 分析)?

c++ - OpenCV 和使用傅立叶变换 dft()

python - 如何在Python中从c文件中获取变量名列表

python - Numpy 3d 数组的切片不一致

python - 根据名称中的某些值动态创建目录和文件

c++ - 袖口 : How to calculate the fft when the input is a pitched array

python - Python 的意外 FFT 结果

python - 向 Seaborn jointploint 添加补丁

python - 如何在没有spark的情况下直接从azure datalake读取 Parquet 文件?