python - 如何使用 fft 在频域中向正弦波添加相移?

标签 python numpy fft phase

我想在频域中移动正弦波

我的想法如下:

  1. 傅里叶变换
  2. 在频域中添加 pi 的相移
  3. 傅里叶逆变换

在代码中:

t=np.arange(0, 6 , 0.001)
values = A*np.sin(t)
ft_values= np.fft.fft(values)
ft_values_phase=ft_values+1j*np.pi
back_again= np.fft.ifft(ft_values_phase)
plt.subplot(211)
plt.plot(t,values)
plt.subplot(212)
plt.plot(t,back_again)

我期望得到两张图像,其中一个波移动了 pi,但是我得到了这个结果

(无相移):

enter image description here

感谢您的帮助!

最佳答案

您没有进行相移。

您所做的是将一个 6000 向量(例如 P)与常数值 P(i) = j π 添加到 Vv 的 FFT。

让我们写成Ṽ = V + P

由于 FFT(和 IFFT)的线性,您所说的 back_again

        ṽ = IFFT(Ṽ) = IFFT(V) + IFFT(P) = v + p

当然,p = IFFT(P) 是差值 values-back_again — 现在,让我们检查一下 p 是什么。 ..

In [51]: P = np.pi*1j*np.ones(6000) 
    ...: p = np.fft.ifft(P) 
    ...: plt.plot(p.real*10**16, label='real(p)*10**16') 
    ...: plt.plot(p.imag, label='imag(p)') 
    ...: plt.legend();

antitransform of P

正如您所看到的,您通过添加 的实数分量来修改,该实数分量本质上是 IFFT 计算中的数值噪声(因此绘图中没有变化) ,这为您提供了 back_again实数部分)和一个虚数尖峰,其高度毫不奇怪地等于 π,对于 t= 0

常数的变换是ω=0处的尖峰,常数(频域中)的反变换是t=0处的尖峰。 p>

另一方面,如果将每个 FFT 项一个常数,您也会将时域信号乘以相同的常数(请记住,FFT 和 IFFT 是线性)。

要做你想做的事,你必须记住,时域中的移位只是(周期性)信号与时移尖峰的(循环)卷积,因此你必须乘以信号的 FFT通过移位尖峰的 FFT。

由于狄拉克分布的傅里叶变换 δ(t-a)exp(-iωa),因此您必须将信号 FFT 的每一项乘以频率依赖项,exp(-iωa)=cos(ωa)-i·sin(ωa)(注意:当然,这些乘法项中的每一项都有单位幅度)。

<小时/>

示例

一些预备知识

In [61]: import matplotlib.pyplot as plt 
    ...: import numpy as np                                                                                           
In [62]: def multiple_formatter(x, pos, den=60, number=np.pi, latex=r'\pi'): 
             ... # search on SO for an implementation
In [63]: def plot(t, x): 
    ...:     fig, ax = plt.subplots() 
    ...:     ax.plot(t, x) 
    ...:     ax.xaxis.set_major_formatter(plt.FuncFormatter(multiple_formatter)) 
    ...:     ax.xaxis.set_major_locator(plt.MultipleLocator(np.pi / 2)) 
    ...:     ax.xaxis.set_minor_locator(plt.MultipleLocator(np.pi / 4)) 

计算以 n 为中心、持续一段 N 的狄拉克分布的离散 FT 的函数

In [64]: def shift(n, N): 
    ...:     s = np.zeros(N) 
    ...:     s[n] = 1.0 
    ...:     return np.fft.fft(s)                                                                                     

让我们绘制一个信号和移位后的信号

In [65]: t = np.arange(4096)*np.pi/1024                                                                               
In [66]: v0 = np.sin(t)                                                                                               
In [67]: v1 = np.sin(t-np.pi/4)                                                                                       
In [68]: f, a = plot(t, v0)                                                                                           
In [69]: a.plot(t, v1, label='shifted by $\\pi/4$');                                                                   
In [70]: a.legend();

enter image description here

现在计算正确尖峰的 FFT(注意 π/4 = (4π)/16)、移位信号的 FFT、s.s. 的 FFT 的 IFFT。最后绘制我们的结果

In [71]: S = shift(4096//16-1, 4096)                                                                                  
In [72]: VS = np.fft.fft(v0)*S                                                                                        
In [73]: vs = np.fft.ifft(VS)                                                                                         
In [74]: f, ay = plot(t, v0)                                                                                          
In [75]: ay.plot(t, vs.real, label='shifted in frequency domain');                                                    
In [76]: ay.legend();

enter image description here

关于python - 如何使用 fft 在频域中向正弦波添加相移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57183126/

相关文章:

python - 使用 python 和 FFT 计算均方位移

image-processing - 带FFT的高斯模糊

python - 字典下的字典是按值复制而不是按引用复制?

python - 加速双曲抛物面算法的最近点

python - 通过scrapy模拟表单登录

python - 如何使用 Numba 并行化数组上的 for 循环

python - 来自 pandas 数据帧行的具有分隔范围的 2D numpy 数组

python - 替换python列表中的特定字符

python - numpy distutils——尝试编译一些东西并在失败时设置标志

python - 检测 FFT 图中的峰值