如何从 Numpy 中的傅立叶变换恢复振幅和相移?
How to recover amplitude, and phase shift from Fourier Transform in Numpy?
我正在尝试编写一个简单的 python 脚本来从傅立叶变换中恢复正弦波的幅度和相位。
对于给定的频率,我应该能够通过计算由傅立叶变换的实数和虚数定义的向量的大小和方向来做到这一点,即:
Amplitude_at_freq = sqrt(real_component_at_freq^2 + imag_component_at_freq^2)
Phase = arctan(imag_component_at_freq/real_component_at_freq)
参考:此视频 1 分 45 秒:https://www.youtube.com/watch?time_continue=106&v=IWQfj05i87g
我已经使用 numpy 的 fft 库编写了一个简单的 python 脚本来尝试重现这一点,但是尽管我完全按照上面的方式写出了我的推导,但我无法获得振幅和相位,尽管我可以恢复我的测试正弦波的原始频率正确。之前的 post and this one Why FFT does not retrieve original amplitude when increasing signal length 指向相同的问题(振幅偏离 2 倍)。具体的解决方案是 "multiply by 2 (half of spectrum is removed so energy must be preserved)," 但我需要澄清这意味着什么。其次,没有提到我恢复相变的问题,振幅的计算与我这里的不同。
# Define amplitude, phase, frequency
_A = 4 # Amplitude
_p = 0 # Phase shift
_f = 8 # Frequency
# Construct a simple signal
t = np.linspace(0, 2*np.pi, 1024 + 1)[:-1]
g = _A * np.sin(_f * t + _p)
# Apply the fourier transform
ff = np.fft.fft(g)
# Get frequency of original signal
ff_ii = np.where(np.abs(ff) > 1.0)[0][0] # Just get one frequency, the other one is just mirrored freq at negative value
print('frequency of:', ff_ii)
# Get the complex vector at that frequency to retrieve amplitude and phase shift
yy = ff[ff_ii]
# Calculate the amplitude
T = t.shape[0] # domain of x; which we will divide height to get freq amplitude
A = np.sqrt(yy.real**2 + yy.imag**2)/T
print('amplitude of:', A)
# Calculate phase shift
phi = np.arctan(yy.imag/yy.real)
print('phase change:', phi)
然而,我得到的结果是:
>> frequency of: 8
>> amplitude of: 2.0
>> phase change: 1.5707963267948957
所以频率是准确的,但我得到的振幅为 2,而本应为 4,相变为 pi/2,而本应为零。
是我数学错了,还是我对 numpy 的 fft 实现的理解不正确?
傅立叶将信号分析为 exp(i.2.pi.f.t)
项的总和,因此它看到
A.sin(2.pi.f1.t)
作为:
-i.A/2.exp(i.2.pi.f1.t)+i.A/2.exp(-i.2.pi.f1.t)
,
这在数学上是相等的。因此,用傅里叶术语来说,正频率 f1 和负频率 f1 分别具有复数值 -A/2.i
和 A/2.i
。所以每个 'side' 只有一半的振幅,但是如果你把它们加在一起(在逆傅立叶变换中)你会得到振幅 A。如果你只看,正负频率的这种分裂就是你缺少的因子 2在频谱的一侧(正或负)。这通常在实践中完成,因为对于真实信号,另一半对于给定的信号来说是微不足道的。
查看精确的数学Euler's formula and Fourier transform。
我正在尝试编写一个简单的 python 脚本来从傅立叶变换中恢复正弦波的幅度和相位。
对于给定的频率,我应该能够通过计算由傅立叶变换的实数和虚数定义的向量的大小和方向来做到这一点,即:
Amplitude_at_freq = sqrt(real_component_at_freq^2 + imag_component_at_freq^2)
Phase = arctan(imag_component_at_freq/real_component_at_freq)
参考:此视频 1 分 45 秒:https://www.youtube.com/watch?time_continue=106&v=IWQfj05i87g
我已经使用 numpy 的 fft 库编写了一个简单的 python 脚本来尝试重现这一点,但是尽管我完全按照上面的方式写出了我的推导,但我无法获得振幅和相位,尽管我可以恢复我的测试正弦波的原始频率正确。之前的 post
# Define amplitude, phase, frequency
_A = 4 # Amplitude
_p = 0 # Phase shift
_f = 8 # Frequency
# Construct a simple signal
t = np.linspace(0, 2*np.pi, 1024 + 1)[:-1]
g = _A * np.sin(_f * t + _p)
# Apply the fourier transform
ff = np.fft.fft(g)
# Get frequency of original signal
ff_ii = np.where(np.abs(ff) > 1.0)[0][0] # Just get one frequency, the other one is just mirrored freq at negative value
print('frequency of:', ff_ii)
# Get the complex vector at that frequency to retrieve amplitude and phase shift
yy = ff[ff_ii]
# Calculate the amplitude
T = t.shape[0] # domain of x; which we will divide height to get freq amplitude
A = np.sqrt(yy.real**2 + yy.imag**2)/T
print('amplitude of:', A)
# Calculate phase shift
phi = np.arctan(yy.imag/yy.real)
print('phase change:', phi)
然而,我得到的结果是:
>> frequency of: 8
>> amplitude of: 2.0
>> phase change: 1.5707963267948957
所以频率是准确的,但我得到的振幅为 2,而本应为 4,相变为 pi/2,而本应为零。
是我数学错了,还是我对 numpy 的 fft 实现的理解不正确?
傅立叶将信号分析为 exp(i.2.pi.f.t)
项的总和,因此它看到
A.sin(2.pi.f1.t)
作为:
-i.A/2.exp(i.2.pi.f1.t)+i.A/2.exp(-i.2.pi.f1.t)
,
这在数学上是相等的。因此,用傅里叶术语来说,正频率 f1 和负频率 f1 分别具有复数值 -A/2.i
和 A/2.i
。所以每个 'side' 只有一半的振幅,但是如果你把它们加在一起(在逆傅立叶变换中)你会得到振幅 A。如果你只看,正负频率的这种分裂就是你缺少的因子 2在频谱的一侧(正或负)。这通常在实践中完成,因为对于真实信号,另一半对于给定的信号来说是微不足道的。
查看精确的数学Euler's formula and Fourier transform。