使用python实现离散时间傅里叶变换的方法
作者:weijifen000 发布时间:2021-10-26 19:44:07
我们经常使用傅里叶变换来计算数字信号的频谱,进而分析数字信号,离散时间傅里叶变换的公式为:
可是自己动手实现一遍才是最好的学习。
在数字分析里面,傅里叶变换默认等时间间隔采样,不需要时间序列,只需要信号数组即可分析。
分析过程如下:
对于含有 n 个样本值的数字信号序列,根据奈奎斯特采样定律,包含的周期数最大为 n/2,周期数为 0 代表直流分量。所以,当周期数表示为离散的 0,1,2,3…n/2 ,总的数目为
n/2+1
个傅里叶变换之后的结果为复数, 下标为 k 的复数 a+b*j 表示时域信号中周期为 N/k 个取样值的正弦波和余弦波的成分的多少, 其中 a 表示 cos 波形的成分, b 表示 sin 波形的成分
首先产生一个长度为 n,一倍周期的 $e^{-jwn} $ (即为 $cos(wn)-jsin(wn) $ )波样本序列.
将数字信号序列中的每一个样本与 1 倍周期的样本波形序列相乘,得到 n 个乘积,将 n 个乘积相加,放入 f[1] 中。
再产生一个长度为 n,两倍周期的 $e^{-jwn} $ (即为 $cos(wn)-jsin(wn) $ )波样本序列,再将数字信号序列中的每一个样本与 2 倍周期的样本波形序列相乘,得到 n 个乘积,将 n 个乘积相加,放入 f[2] 中。依次重复。
对于 0 倍周期,即直流分量来说,可以认为产生的是 0 倍周期的样本波形,重复操作,放入 f[0] 即可。
这样就得到了数字信号序列的傅里叶变换
使用方法:
从以上过程得到数字序列的傅里叶变换之后,如果想要得到真正频谱,还需要做处理:
计算出的每一个频率下的幅值需要除以时间序列的长度,类似求平均的过程
每一个频率下的幅值是一个复数,需要对它求模,而且因为在负频率处也有值,所以需要对于实信号需要乘 2
频率的序列为 0 到采样率的一半,长度为 n/2+1
完整程序:
# 离散时间傅里叶变换的 python 实现
import numpy as np
import math
import pylab as pl
import scipy.signal as signal
import matplotlib.pyplot as plt
sampling_rate=1000
t1=np.arange(0, 10.0, 1.0/sampling_rate)
x1 =np.sin(15*np.pi*t1)
# 傅里叶变换
def fft1(xx):
# t=np.arange(0, s)
t=np.linspace(0, 1.0, len(xx))
f = np.arange(len(xx)/2+1, dtype=complex)
for index in range(len(f)):
f[index]=complex(np.sum(np.cos(2*np.pi*index*t)*xx), -np.sum(np.sin(2*np.pi*index*t)*xx))
return f
# len(x1)
xf=fft1(x1)/len(x1)
freqs = np.linspace(0, sampling_rate/2, len(x1)/2+1)
plt.figure(figsize=(16,4))
plt.plot(freqs,2*np.abs(xf),'r--')
plt.xlabel("Frequency(Hz)")
plt.ylabel("Amplitude($m$)")
plt.title("Amplitude-Frequency curve")
plt.show()
plt.figure(figsize=(16,4))
plt.plot(freqs,2*np.abs(xf),'r--')
plt.xlabel("Frequency(Hz)")
plt.ylabel("Amplitude($m$)")
plt.title("Amplitude-Frequency curve")
plt.xlim(0,20)
plt.show()
此处实现的是传统的傅里叶变换,这种方法实际已经不用了,现在使用快速傅里叶变换,其实两种是等价的,但是快速傅里叶变换时间复杂度要小很多。
来源:https://blog.csdn.net/weijifen000/article/details/79598258


猜你喜欢
- python去除列表中的空值元素实战技巧产生需求的原因:最近都在使用python做一些小demo,尤其是经常会用python做一些关于数据处
- 或者你还有其它的sysadmin权限的账号,你可以用此账号登录,重置SA密码。 但是在以下情况下,怎么办呢?1. SA密码丢失或者SA账号被
- 方法一:在目前绝大部分数据库有分布式查询的需要。下面简单的介绍如何在oracle中配置实现跨库访问。比如现在有2个数据库服务器,安装了2个数
- 多层索引的创建普通-多个index创建在创建数据的时候加入一个index列表,这个index列表里面是多个索引列表Series多层索引的创建
- 1、效果图2、安装npm install --save nprogress基本用法NProgress.start();NProgress.d
- 前言:设计模式在我们编程中是十分重要的!设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用
- 一、MySQL Workbench的下载Workbench是MySql图形化的管理工具,可以在Workbench里输入MySql的语句,这可
- BP神经网络是最简单的神经网络模型了,三层能够模拟非线性函数效果。难点:如何确定初始化参数?如何确定隐含层节点数量?迭代多少次?如何更快收敛
- 还是一样,先上代码: <script> var f = function g() { return 1; }; if (fals
- var GB2312UnicodeConverter = { ToUnicode: function (
- vue代码压缩优化设置productionSourceMap为false如果不需要生产环境的 source map,可以将其设置为 fals
- 代码的作用在于保证在上端缓存服务失效(一般来说概率比较低)时,形成倒瓶颈,从而能够保护数据库,数据库宕了,才是大问题(比如影响其他应用)。假
- String(字符型)–%s integer(整形)–%d float(浮点型)–%f实例我们需要输出一个人的信息代码:#coding=ut
- 在使用SQL Server 的过程,中由于经常需要从多个不同地点将数据集中起来或向多个地点复制数据,所以数据的导出,导入是极为常见的操作.我
- NopCommerce支持灵活的插件机制,所谓Web系统插件,其实也就是可以像原系统的一部分一样使用。Web系统的使用方式就是客户端发送一个
- 为了访问数据库,就要提供数据库连接类,在C#中,是通过Connection类来实现的四种类型的连接方式SQLConnectionADOCon
- 学了几天正则,差不多该总结整理写成果了,之前就想写语法高亮匹配来着,不过水平不够,看着例子都不理解。那么我们来分析下两位大神 次碳酸钴 和
- 首先:我们介绍一下socket什么是socket:1. socket 在操作系统中它是处于应用层与传输层的抽象层,它是一组操作起来非常简单的
- 自动换行问题,正常字符的换行是比较合理的,而连续的数字和英文字符常常将容器撑大,挺让人头疼,下面介绍的是CSS如何实现换行的方法对于div,
- 应原书编辑要求,先在文章顶部给出链接:《Everything You Know About CSS Is Wrong》http://www.