快速傅里叶变换(FFT),离散傅里叶变换(DFT)

news/2024/7/7 22:16:29

快速傅里叶变换(FFT),离散傅里叶变换(DFT)

傅里叶变换
离散傅里叶变换(DFT)用于将一般时间序列变换到频域(即使它们是非周期的),即计算频谱。
计算DFT所需的DFT长度LDFT使用快速傅里叶变换(FFT)算法。np.fft.fft(x,L_DFT)必须选择得比信号x长。通常,如果DFT长度LDFT是2的幂,则fft算法最快。因此,在第12-14行中,检查DFT长度,发现L_DFT=2**14足够长,即比信号x(详见下文)长。

fs=8000 # sampling frequency

t=np.arange(0,2,1/fs) # time vector
f1=1230               # fundamental frequency in Hz
f2=1800               # fundamental frequency in Hz

sin1=np.sin(2*np.pi*f1*t)
sin2=np.sin(2*np.pi*f2*t+np.pi)/2
x=sin1+sin2

# DFT of the signal mixture
L_DFT=2**14 # DFT length

# we first check if the DFT length is longer than the signal length
print('Signal length is ' + str(len(x)))
print('DFT length is ' + str(L_DFT))

# perform DFT using the FFT algorithm
X = np.fft.fft(x,L_DFT)

# create a frequency vector to order negative /positive frequencies 
f1=np.linspace(0,fs/2,int(L_DFT/2))    # the positive frequencies (up to fs/2)
f2=np.linspace(-fs/2,0,int(L_DFT/2))   # the negative frequencies
f = np.concatenate([f1, f2])

# plot signals
plt.figure(figsize=(12,8))
plt.subplot(2,2,1)
plt.plot(t[:160],x[:160])
plt.xlabel('time $t$ in seconds')
plt.ylabel('$x(t)$')
plt.subplot(2,2,2)
plt.plot(f, np.abs(X))
plt.title('Absolute value of the DFT of a signal mixture')
plt.xlabel('frequency $f$ in Hz')
plt.ylabel('$|x(f)|$')
plt.subplot(2,2,3)
plt.plot(f, np.real(X))
plt.xlabel('frequency $f$ in Hz')
plt.ylabel('$\mathrm{Re}\{x(f)\}$')
plt.subplot(2,2,4)
plt.plot(f, np.imag(X))
plt.xlabel('frequency $f$ in Hz')
plt.ylabel('$\mathrm{Im}\{x(f)\}$')
plt.tight_layout()
  • sin2=np.sin(2np.pif2*t+np.pi)/2 why it add np.pi then divide 2 is that the way to discribe phi?
  • np.real(X)
  • np.imag(X)
    可以看出,时域表示(左上角)不容易解释。频谱的大小(右上角)最清楚地表明,信号由两个正弦波部分组成,还可以看到信号在哪些频率下包含功率。从下方面板中的实部和虚部,我们可以看到光谱含量在实部和虚部之间“区分”。对于这个例子,我们可以得出结论,震级|x(f)|最容易解释。
    提示:使用numpy函数fft可以简化上面示例中频率向量f的相当复杂的构造。fftshift(有关链接,请参见上面的ILO)。

找到合适的DFT/FFT长度-Helper函数计算下一次2的幂
DFT/FFT的一个重要参数是长度LDFT或LFFT。为了确定合适的FFT长度LFFT,我们感兴趣的是一个大于时域(输入)序列长度的数字。FFT通常被实现为各种类型和长度的输入信号有效计算DFT的众多算法的集合,通常使用软件库FFTW(这里为真正感兴趣的人撰写的科学论文)。在运行时,为信号类型(例如,实值、复值等)和长度LFFT选择有效算法。
2的幂有利于使用高效的Cooley–Tukey FFT算法或Radix-2实现FFT()。因此,我们将使用下面的助手函数来确定信号长度的下一个二次幂。这个函数的确切工作方式超出了本课程的范围,但您应该能够使用它。

计算Next-Power-of-2的函数
以下函数nextPowerOf2(L)和nextPowerPOf2_simple(L)是计算适当的FFT长度L_FFT的两个实现,该长度是2的幂,并且总是大于信号长度L。如果您感兴趣,可以使用不同的L,例如,使用下面代码中的主注释中提供的示例。这些函数的确切工作方式超出了本实验表的范围。


def nextPowerOf2(L):
    '''
    Calculates the smallest power of 2 which is bigger than the length of input variable L
    
    This helper function can be used to calculate an appropriate 
    length for an DFT which is longer than the signal length L and is a power of 2.
    
    Input:
        L: int
            signal length
    Output:
        p: integer which is greater or equal than L and a power of 2
    
    Examples:
        for L in range(20):
            print('nextPowerOf2(L) for L='+str(L)+' is '+str(nextPowerOf2(L)))
            
        x=ones(11)
        L_FFT=nextPowerOf2(len(x))
    '''
    if (L<2):
        return 2
    # If n is a power of 2 then return n 
    if (L and not(L & (L - 1))):
        return L
    # If n is NOT a power of 2 
    p = 1
    while (p < L) :
        p <<= 1 
    return p

def nextPowerOf2_simple(L):
    '''
    Calculates the smallest power of 2 which is bigger than the length of input variable L
    
    This helper function can be used to calculate an appropriate 
    length for an DFT which is longer than the signal length L and is a power of 2.
    
    Input:
        L: int
            signal length
    Output:
        p: integer which is greater or equal than n and a power of 2
    
    Examples:
        for L in range(20):
            print('nextPowerOf2(L) for L='+str(L)+' is '+str(nextPowerOf2_simple(L)))
            
        x=ones(11)
        L_FFT=nextPowerOf2_simple(len(x))
    '''
    return int(np.max([2,2**np.ceil(np.log2(L))]))

for L in range(20):
    print('nextPowerOf2(L) for L='+str(L)+' is '+str(nextPowerOf2(L)))

# this version would create a warning for L=0, to put in 0 as length of the signal should also not happen
for L in range(20):
    print('nextPowerOf2_simple(L) for L='+str(L)+' is '+str(nextPowerOf2_simple(L)))

http://lihuaxi.xjx100.cn/news/133247.html

相关文章

Linux(12)进程间通信之管道

文章目录匿名管道pipe通信基本过程父进程控制子进程父进程控制多个子进程管道特点总结命名管道进程是具有独立性的&#xff0c;进程间想要交互数据&#xff0c;成本会非常高进程间通信的目的&#xff1a; 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程资源共享…

快速记忆杂乱无章

章节章节01 - 计算机组成原理与体系结构07 - 法律法规与标准化与多媒体基础02 - 操作系统基本原理08 - 设计模式03 - 数据库系统09 - 软件工程04 - 计算机网络10 - 面向对象05 - 数据结构与算法11 - 结构化开发与UML06 - 程序设计语言与语言处理程序基础12 - 下午题历年真题End…

【一文讲明白什么是云原生,有什么优势】

目录 什么是云原生&#xff1f; 云原生有什么优势&#xff1f; 云原生时代开发者必须掌握哪些能力&#xff1f; 微服务 网关 Kubernetes DevOps ServiceMesh 十二要素应用程序 总结 什么是云原生&#xff1f; 最近看见云原生比较火&#xff0c;越来越多的编程语言、框架开…

中英文说明书丨艾美捷MAPT单克隆抗体

艾美捷MAPT单克隆抗体英文说明书&#xff1a; Specification&#xff1a; Product Description:Mouse monoclonal antibody raised against a partial recombinant MAPT. Immunogen:MAPT (NP_058519.2, 167 a.a. ~ 266 a.a) partial recombinant protein with GST tag. MW o…

Spring 事务编程实践

Spring 事务实战 文章目录Spring 事务实战什么是 Spring 事务&#xff1f;声明式事务使用举例编程式事务使用举例声明式事务常见问题事务不生效Case1&#xff1a;类内部访问Case2&#xff1a;非 public 可重载方法Case3&#xff1a;异常不匹配(重点)Case4&#xff1a;多线程Cas…

LeetCode-754. 到达终点数字【数学】

LeetCode-754. 到达终点数字【数学】题目描述&#xff1a;解题思路一&#xff1a;三行代码。发现规律&#xff0c;将target取绝对值不影响结果。若未到达终点继续走即可。情况一&#xff1a;若最后s-target为偶数或0&#xff0c;我们发现可以在之前里面反走一步即可&#xff08…

MySQL系列-高级-深入理解Mysql事务隔离级别与锁机制01

MySQL系列-高级-深入理解Mysql事务隔离级别与锁机制1. 概述2.事务及其ACID属性1. ACID2. 并发事务处理带来的问题3. 事务隔离级别3. 锁1. 锁分类2. MylSAM表读/写锁案例分析1. 读锁操作2. 写锁操作3. InnoDB行锁案例分析行锁介绍行锁演示演示一演示二演示三演示2和演示3的问题本…

喜相逢再递表港交所:非控股股东均亏损,已提前“套现”数千万元

作者|汤汤 来源|贝多财经 近日&#xff0c;喜相逢控股有限公司&#xff08;下称“喜相逢”&#xff09;在港交所又一次递交招股书&#xff0c;准备在港交所主板上市。此前的2019年12月31日、2020年7月21日、2021年7月30日&#xff0c;喜相逢曾三度在港交所递交上市申请&#…