如何从Numpy中的傅立叶变换中恢复幅度和相移?

时间:2019-10-20 18:07:08

标签: numpy fft amplitude

我正在尝试编写一个简单的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脚本来尝试重现该脚本,但是尽管写出了与上述完全相同的推导,但是尽管我可以恢复测试的原始频率,但仍无法获得振幅和相位正弦波正确。上一篇Calculating amplitude from np.fft和上一篇Why FFT does not retrieve original amplitude when increasing signal length指出了相同的问题(振幅相差2倍)。具体来说,解决方案是“乘以2(消除了一半的光谱,因此必须保留能量)”,但是我需要澄清这是什么意思。其次,我没有提到恢复相变的问题,其幅度的计算方法与我在这里得到的不同。

# 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实现的理解不正确?

1 个答案:

答案 0 :(得分:2)

Fourier将信号分析为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.iA/2.i。因此,每个“边”仅具有一半的幅度,但是如果将它们加在一起(在傅立叶逆变换中),则将获得幅度A。如果只看一个,则正负频率的拆分就是缺少因子2的地方。 (正或负)频谱。这样做通常是在实践中完成的,因为对于真实信号,另一半对于给定的信号来说微不足道。

仔细研究数学Euler's formulaFourier transform