简单DFT系数=>幅度/频率=>曲线

时间:2018-08-12 09:35:03

标签: python numpy math fft dft

我正在尝试使用numpy和pyplot在Python中进行DFT和FFT。

我的样本向量是

x = np.array([1,2,4,3]

该向量的DFT系数为

K = [10+0j, -3+1j, 0+0j, -3-1j]

所以基本上我们有10,-3 + i,0和-3-1i作为DFT系数。

我现在的问题是要得到正弦和余弦的组合以适合所有4个点。

假设我们的采样率为1hz。

这是我的代码:

from matplotlib import pyplot as plt
import numpy as np

x = np.array([1,2,4,3])

fft = np.fft.fft(x)

space = np.linspace(0,4,50)
values = np.array([1,2,3,4])

cos0 = fft[0].real * np.cos(0 * space)

cos1 = fft[1].real * np.cos(1/4 * np.pi * space)
sin1 = fft[1].imag * np.sin(1/4 * np.pi * space)

res = cos0 + cos1 + sin1

plt.scatter(values, x, label="original")
plt.plot(space, cos0, label="cos0")
plt.plot(space, cos1, label="cos1")
plt.plot(space, sin1, label="sin1")
plt.plot(space, res, label="combined")

plt.legend()

结果我得到了情节:

img

为什么最终曲线未达到任何点?

感谢您的帮助。谢谢!

编辑:

N = 1000
dataPoints = np.linspace(0, np.pi, N)
function = np.sin(dataPoints)
fft = np.fft.fft(function)

F = np.zeros((N,))
for i in range(0, N):
    F[i] = (2 * np.pi * i) / N
F_sin = np.zeros((N,N))
F_cos = np.zeros((N,N))

res = 0
for i in range(0, N):
    F_sin[i] = fft[i].imag / 500 * np.sin(dataPoints * F[i])
    F_cos[i] = fft[i].real / 500* np.cos(dataPoints * F[i])
    res = res + F_sin[i] + F_cos[i] 
plt.plot(dataPoints, function)
plt.plot(dataPoints, res)

我的情节看起来像:

img

我在哪里失败?

2 个答案:

答案 0 :(得分:0)

您的测试向量x看起来有点像sawtooth,因为它呈线性上升,然后开始下降,但是由于数据点很少,很难分辨出它是什么信号。这具有无限的FFT序列,这意味着其中包含许多更高的谐波频率分量。因此,要用DTF系数描述它并接近原始点,就必须使用

  1. 更高的采样率,以获取有关更高频率的信息(您应该了解nyquist theorem
  2. 更多数据点(样本),因此您可以提取有关信号频率的更精确信息)这意味着您必须在数组“ x”中包含更多项。

此外,您可以尝试适应一些更简单的信号。您如何尝试使正弦信号适合启动?生成1000个低频正弦数据点(每1000个样本1Hz或1个周期),然后对其运行DTF,以检查您的代码是否有效。

答案 1 :(得分:0)

有一些错误:

  • 您分配给原始值的xs偏离了一个
  • 您分配给fft [1]的频率不正确
  • 系数缩放不正确

此作品有效:

from matplotlib import pyplot as plt
import numpy as np

x = np.array([1,2,4,3])

fft = np.fft.fft(x)

space = np.linspace(0,4,50)
values = np.array([0,1,2,3])

cos0 = fft[0].real * np.cos(0 * space)/4

cos1 = fft[1].real * np.cos(1/2 * np.pi * space)/2
sin1 = -fft[1].imag * np.sin(1/2 * np.pi * space)/2

res = cos0 + cos1 + sin1

plt.scatter(values, x, label="original")
plt.plot(space, cos0, label="cos0")
plt.plot(space, cos1, label="cos1")
plt.plot(space, sin1, label="sin1")
plt.plot(space, res, label="combined")

plt.legend()
plt.show()