python - 傅里叶变换结果中的意外相移 (np.fft)
问题描述
我正在寻找对傅里叶变换原理的澄清。
我尝试做一些非常简单的事情:创建一个信号(具有给定频率和相移的正弦波)并使用傅里叶变换重新创建其参数。频率估计工作正常,但在相位方面,看起来我得到了系统偏移(-pi/2)。
import numpy as np
import matplotlib.pyplot as plt
duration = 4.0 # lenght of window (in sec)
ticks_per_sec = 400.0 # sampling interval
samples = int(ticks_per_sec*duration)
phase_shift = np.pi / 2 # sin wave shift in angle
freq = 1 # sine wave freq in Hz
phase_shift = round(ticks_per_sec/freq * phase_shift/(2*np.pi)) # angle value translated to no of ticks
t = np.arange(phase_shift, samples+phase_shift) / ticks_per_sec
s = 1 * np.sin(2.0 * np.pi * freq * t)
N = s.size
fig, axs = plt.subplots(1, 3, figsize=(18, 6))
axs[0].grid(True)
axs[0].set_ylabel("Amplitude")
axs[0].set_xlabel("Time [s]")
axs[0].set_title(f"F: {freq}, Phase shift: {phase_shift} ticks.")
axs[0].plot(np.arange(samples)/ticks_per_sec, s)
f = np.linspace(0, ticks_per_sec, N)
fft = np.fft.fft(s)
peak_pos = np.argmax(np.abs(fft[:N//2]))
axs[1].set_ylabel("Amplitude")
axs[1].set_xlabel("Frequency [Hz]")
axs[1].set_title(f"Peak bar: {peak_pos}")
barlist = axs[1].bar(f[:N // 2], np.abs(fft)[:N // 2] * (1 / (N//2)), width=1.5) # 1 / N is a normalization factor
barlist[peak_pos].set_color('r')
axs[2].set_ylabel("Angle")
axs[2].set_xlabel("Frequency [Hz]")
axs[2].set_title(f"Peak angle: {np.angle(fft[peak_pos])}")
barlist = axs[2].bar(f[:N // 2], np.angle(fft)[:N // 2], width=1.5)
barlist[peak_pos].set_color('r')
fig.show()
如果我的代码中存在我无法注意到的错误,或者我误解了某些内容,请帮助我。
先感谢您。
解决方案
您的代码很好,这不是编程问题。
让我们回想一下,正弦波可以表示为具有相移的余弦波(反之亦然),现在请记住,正弦函数是实傅里叶基中相对于余弦的 -pi/2 的固有相移。
这意味着您的代码在替换为 时应输出 pi/2 相位角np.sin
,np.cos
即返回输入phase_shift
,或者等效地,在指定时返回零相位角phase_shift = np.pi / 2
,即 phase shift
和正弦相位相互补偿。
推荐阅读
- angular - 输入文件选择
- php - 是否有任何功能可以停止 foreach 循环?
- python - 如何将2个字符串转换为列表python?
- ruby - 我需要关于 string.index 的建议
- c++ - gcc 编译的 C++ 中不包含调试符号
- symfony - Twig 检索模板 symfony 中翻译的所有变量
- python - 有效地检查数据框的日期是否在一个范围内,并返回一个计数
- powerbi - 在 Power BI 中合并来自多个工作簿的 Excel 工作表
- json - 如何序列化 Template::render 的上下文
- guice - 是否可以使用 Guice 注入任意类型的实现?