首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用fft在频域上对正弦波加相移?

如何用fft在频域上对正弦波加相移?
EN

Stack Overflow用户
提问于 2019-07-24 12:36:41
回答 2查看 4.6K关注 0票数 2

我想把正弦波移到频域。

我的想法如下:

  1. 傅里叶变换
  2. 在频域上增加π的相移
  3. 逆傅里叶变换

代码:

代码语言:javascript
复制
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移动,但是我得到了这个结果。

(无相移):

谢谢你的帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-24 13:36:18

你没有发生相移。

您所做的是添加一个6000-向量,例如P,其常数为P(i) =jπto V,即v.

让我们写Ṽ=V+ P。

由于快速傅立叶变换(和IFFT)的线性度,你所说的back_again

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

其中,p= IFFT(P)是差分values-back_again -现在,让我们检查什么是p.

代码语言:javascript
复制
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();

如您所见,您修改了values,为t=0添加了一个实际的ṽ分量,它本质上是计算IFFT时的数值噪声(因此在图中没有变化,这给了您back_again的真实部分)和一个假想的尖峰,它的高度不出所料地等于π。

一个常数的变换在ω=0上是一个尖峰,一个常数的反变换(在频域上)在t=0上是一个尖峰。

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

要想做你想做的事,你必须记住,时域上的偏移只是周期信号与一个时移尖峰的(圆形)卷积,所以你必须把信号的FFT乘以移位尖峰的FFT。

由于狄拉克分布( the )的傅里叶变换是exp(-iωa),所以必须将信号的每个项乘以一个频率相关项,exp(-iωa)=cos(ωa)-i·sin(ωa) (注:当然,每个乘法项都有单位振幅)。

一个例子

一些预演

代码语言:javascript
复制
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中狄拉克分布离散FT的函数

代码语言:javascript
复制
In [64]: def shift(n, N): 
    ...:     s = np.zeros(N) 
    ...:     s[n] = 1.0 
    ...:     return np.fft.fft(s)                                                                                     

让我们画一个信号和一个移位的信号

代码语言:javascript
复制
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();

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

代码语言:javascript
复制
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();

票数 3
EN

Stack Overflow用户

发布于 2019-07-27 17:50:23

太好了,帮了忙!对于任何想要这样做的人,这里有一个python文件:

代码语言:javascript
复制
import numpy as np
from matplotlib.pyplot import plot, legend
def shift(n, N): 
    s = np.zeros(N) 
    s[n] = 1.0 
    return np.fft.fft(s)  
t = np.linspace(0, 2*np.pi,1000) 
v0 = np.sin(t)                                                                                               
S = shift(1000//4, 1000)  # shift by pi/4
VS = np.fft.fft(v0)*S 
vs = np.fft.ifft(VS)
plot(t, v0 , label='original' )
plot(t,vs.real,label='shifted in frequency domain')
legend()

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57183126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档