numpy.fft.fft() 在 Python 中的实现

Gre*_*uce 6 python numpy fft matplotlib

我正在尝试使用该fft函数获取周期信号的频谱。然后绘制变换的幅度和相位。幅度图没问题,但相位图完全出乎意料。例如,我使用了函数 Sin³(t) 和 Cos³(t)。我使用的代码是:

import matplotlib.pyplot as plt
import numpy.fft as nf
import math
import numpy as np
pi = math.pi

N=512

# Sin³(x)
t=np.linspace(-4*pi,4*pi,N+1);t=t[:-1]
y=(np.sin(t))**3
Y=nf.fftshift(nf.fft(y))/N
w=np.linspace(-64,64,N+1);w=w[:-1]

plt.figure("0")
plt.subplot(2,1,1)
plt.plot(w,abs(Y),'ro',lw=2)
plt.xlim((-4,4))
plt.ylabel(r"$|Y|$",size=16)
plt.title("Spectrum of sin\u00B3(t)")
plt.grid(True)
plt.subplot(2,1,2)
ii=np.where(abs(Y)>1e-3)
plt.plot(w[ii],np.angle(Y[ii]),'go',lw=2)
plt.xlim((-4,4))
plt.ylabel(r"Phase of $Y$",size=16)
plt.xlabel(r"$\omega$",size=16)
plt.grid(True)

# Cos³(x)

t=np.linspace(-4*pi,4*pi,N+1);t=t[:-1]
y=(np.cos(t))**3
Y=nf.fftshift(nf.fft(y))/N
w=np.linspace(-64,64,N+1);w=w[:-1]

plt.figure("1")
plt.subplot(2,1,1)
plt.plot(w,abs(Y),'ro',lw=2)
plt.xlim((-4,4))
plt.ylabel(r"$|Y|$",size=16)
plt.title("Spectrum of cos\u00B3(t)")
plt.grid(True)
plt.subplot(2,1,2)
ii=np.where(abs(Y)>1e-3)
plt.plot(w[ii],(np.angle(Y[ii])),'go',lw=2)
plt.xlim((-4,4))
plt.ylabel(r"Phase of $Y$",size=16)
plt.xlabel(r"$\omega$",size=16)
plt.grid(True) 
Run Code Online (Sandbox Code Playgroud)

得到的图是:

i) 对于 Sin³(t) - Sin³(t) 的频谱幅度和相位

ii) 对于 Cos³(t) - Cos³(t) 的频谱幅度和相位

正如您在上面的链接中看到的,两个函数的大小都很好。Sin³(t) 的频谱相位如预期的那样正确。

由于 Cos³(t) 是实数和偶数,并且以复指数形式展开表明系数的相位为 0。但绘制的图形显示了完全不同的答案(参见2):在 w=-3 时,相位接近 5弧度。我犯了什么错误,实现 FFT 的正确方法是什么。

Ral*_*lph 3

np.fft表现符合预期;是你的阴谋造成了混乱。致电plt.tight_layout()应该可以帮助您解决问题:

\n\n

成本谱 t ^ 3

\n\n

如果仔细查看 cos\xc2\xb3(t) 相位的 y 轴,您会发现这些值都有一个 1e-17 前置因子。因此,当 w = -3 时,相位并不接近5 弧度,它实际上接近 5e-17 弧度(实际上为零)。

\n\n

我在研究这个问题时整理了你的代码:

\n\n
import matplotlib.pyplot as plt\nimport numpy.fft as nf\nimport numpy as np\n\nplt.rcParams[\'axes.grid\'] = True\n\npi = np.pi\nN = 512\n\nt = np.linspace(-4*pi, 4*pi, N+1)[:-1]\n\n\ndef fft_func(x, func, N):\n    y = func(x) ** 3\n    Y = nf.fftshift(nf.fft(y)) / N\n    w = np.linspace(-64, 64, N+1)[:-1]\n    return y, Y, w\n\n\ndef plot_mag_phase(w, Y, func_name):\n    fig, ax = plt.subplots(2, 1)\n\n    ii = np.where(abs(Y) > 1e-3)\n\n    ax[0].plot(w, abs(Y), \'ro\', lw=2)\n    ax[1].plot(w[ii], np.angle(Y[ii]), \'go\', lw=2)\n\n    ax[0].set_xlim(-4, 4)\n    ax[1].set_xlim(-4, 4)\n\n    ax[0].set_ylabel("$|Y|$", size=16)\n    ax[1].set_ylabel("Phase of $Y$", size=16)\n\n    ax[0].set_title("Spectrum of {}\\u00B3(t)".format(func_name))\n    ax[1].set_xlabel(r\'$\\omega$\', size=16)\n\n    fig.tight_layout()\n\n# sin x ^ 3\ny, Y, w = fft_func(t, np.sin, N)\nplot_mag_phase(w, Y, \'sin\')\n\n# cos x ^ 3\ny, Y, w = fft_func(t, np.cos, N)\nplot_mag_phase(w, Y, \'cos\')\n
Run Code Online (Sandbox Code Playgroud)\n