logo资料库

北邮电子院专业实验一实验报告.docx

第1页 / 共22页
第2页 / 共22页
第3页 / 共22页
第4页 / 共22页
第5页 / 共22页
第6页 / 共22页
第7页 / 共22页
第8页 / 共22页
资料共22页,剩余部分请下载后查看
专业实验实验报告 实验 1 1. 需求分析 编程实现傅里叶变换,且不用 FFT。由于不能直接用 FFT 函数,故 考虑用傅里叶变换的定义来实现快速傅里叶变换,对傅里叶变换之后 产生的时域数据进行排序,最后用图像的形式展现。 2. 系统环境 Pycharm2019.3.4 3. 数据库设计 引用 matplotlib、sys、numpy 库,使用 Qt5 from PyQt5.QtWidgets import * import sys import numpy as np import matplotlib matplotlib.use("Qt5Agg") # 声明使用 QT5 from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg from matplotlib.figure import Figure from learn import Ui_Form 4.系统实现 1)程序功能模块划分 learn 文件创建图形窗口,math 文件对信号进行处理并显示 函数: def __init__(self, width=5, height=4, dpi=100):创建绘图窗口 def __init__(self):信号产生 def plot_DFT(self, fs, time):对信号上的点采样并进行离散型傅里叶变换 def plot_FFT(self, fs, time):递归的 FFT 运算
def Ploral_Add(self, a, b): 复数加法 def Ploral_Sub(self, a, b): 复数减法 def Ploral_Mul(self, a, b): 复数乘法 def FFT(self, a, lim): FFT 变换算法 def FFt_change(self, s, lim): 给传过来的时域数据排序 def FFT_high(self, fs, time): 迭代的 FFT 2)总体流程和各部分流程 3)核心代码 生成图形窗口 class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(1000, 800) self.gridLayout = QtWidgets.QGridLayout(Form) self.gridLayout.setContentsMargins(20, 20, 20, 20)
self.gridLayout.setObjectName("gridLayout") self.groupBox = QtWidgets.QGroupBox(Form) self.groupBox.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop) self.groupBox.setObjectName("groupBox") self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 1) self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "傅里叶变换")) # self.groupBox.setTitle(_translate("Form", "绘制图表")) 复数加法 def Ploral_Add(self, a, b): # 复数加法 c = [a[0] + b[0], a[1] + b[1]] return c 复数减法 def Ploral_Sub(self, a, b): # 复数减法 c = [a[0] - b[0], a[1] - b[1]] return c 复数乘法 def Ploral_Mul(self, a, b): # 复数乘法 c = [a[0]*b[0] - a[1]*b[1], a[0]*b[1] + a[1]*b[0]] return c 变换公式: def plot_DFT(self, fs, time): # 傅里叶变换按照公式 fs 是采样频率 , time 是整个采样的时间 单位 resolution = fs * time # 计算出总共的点数 fre = 1 t = np.arange(0.0, time, (time / resolution)) # 时域的 t 轴 s = 2 * np.cos(2 * np.pi * t * fre) # 自己定义的一个时域的函数 一个幅值为 2 频率为 fre 的 cos 是 S 函数 f_x = range(0, resolution) f_cos = [] f_sin = [] for k in f_x: # 傅 里 叶 变 换 公 式 , 每 个 频 率 点 的 值 等 于 时 域 中 每 个 点 X[k] = x[n] * exp(-2*j*pi*k*n/N)的和 # exp 可以用欧拉公式转换成 cos 跟 sin f_cos_cache = 0 f_sin_cache = 0 for n in f_x: f_cos_cache += s[n] * np.cos((2 * np.pi * k * n) / resolution)
f_sin_cache += s[n] * np.sin((2 * np.pi * k * n) / resolution) f_cos.append(f_cos_cache) f_sin.append(f_sin_cache) f_cos_child = f_cos[0:int(resolution/2)] # 截取一半的点, 另一半的点是无效的 f_cos_max = max(f_cos_child) f_cos_index = f_cos_child.index(max(f_cos_child)) f_sin_child = f_sin[0:int(resolution / 2)] f_sin_max = max(f_sin_child) f_sin_index = f_sin_child.index(max(f_sin_child)) v_cos = np.sqrt(f_cos_max * f_cos_max + f_sin_child[f_cos_index] * f_sin_child[f_cos_index]) * 2 / resolution p_cos = np.arctan(f_sin_child[f_cos_index] / f_cos_max) / np.pi v_sin = np.sqrt(f_sin_max * f_sin_max + f_cos_child[f_sin_index] * f_cos_child[f_sin_index]) * 2 / resolution p_sin = np.arctan(f_sin_max / f_cos_child[f_sin_index]) / np.pi print('f_cos 频率是', f_cos_index * fs / resolution) print('f_cos 幅值是', v_cos) print('f_cos 相位是', p_cos) print('f_sin 频率是', f_sin_index * fs / resolution) print('f_sin 幅值是', v_sin) print('f_sin 相位是', p_sin) self.F.axes1 = self.F.fig.add_subplot(121) # 添加图像 121 是 1 行 2 列第 1 幅图 self.F.axes1.plot(t, s) self.F.axes1.set_title('Time') self.F.axes2 = self.F.fig.add_subplot(222) # 添加图像 222 是 2 行 2 列第 2 幅图 self.F.axes2.scatter(f_x, f_cos) self.F.axes2.set_title('Frequency_cos') self.F.axes3 = self.F.fig.add_subplot(224) # 添加图像 222 是 2 行 2 列第 4 幅图 self.F.axes3.scatter(f_x, f_sin) self.F.axes3.set_title('Frequency_sin') print(f_cos) def plot_FFT(self, fs, time): # 递归的 FFT resolution = fs * time # 计算出总共的点数 fre = 1 t = np.arange(0.0, time, (time / resolution)) s = 2 * np.cos(2 * np.pi * t * fre) # 时域的 t 轴 # 自己定义的一个时域的函数 一个幅值为 2 频率为 fre 的 cos 函数 f = [] # 将时域的数据当做复数的实数部分, 复数部分补零 for i in range(0, resolution):
f_cache = [s[i], 0] f.append(f_cache) self.FFT(f, len(f)) # 递归的 FFT f_show = [] # 将算出来的数据 a+bi 进行 c = a*a + b*b ,再对 c 开方, 并存入一个列表 用于显 示频域的图像 for i in range(0, resolution): f_show.append(np.sqrt(f[i][0]*f[i][0] + f[i][1]*f[i][1])) self.F.axes1 = self.F.fig.add_subplot(121) self.F.axes1.plot(t, s) self.F.axes1.set_title('Time') self.F.axes2 = self.F.fig.add_subplot(222) self.F.axes2.scatter(t, f_show) self.F.axes2.set_title('Frequency_cos') 实现 fft 算法 def FFT(self, a, lim): # 递归的 FFT 变换算法 if lim == 1: return a a0 = [] a1 = [] for i in range(0, lim >> 1): a0.append(a[i*2]) a1.append(a[i * 2 + 1]) self.FFT(a0, lim >> 1) self.FFT(a1, lim >> 1) wn = [np.cos(2 * np.pi / lim), np.sin(2 * np.pi / lim)] w = [1, 0] for k in range(0, lim >> 1): a[k] = self.Ploral_Add(a0[k], self.Ploral_Mul(w, a1[k])) a[k + (lim >> 1)] = self.Ploral_Sub(a0[k], self.Ploral_Mul(w, a1[k])) w = self.Ploral_Mul(w, wn) def FFt_change(self, s, lim): # 给传过来的时域数据排序 if lim == 2: return s a0 = [] a1 = [] for i in range(0, lim): if i % 2: a1.append(s[i]) else:
a0.append(s[i]) a0 = self.FFt_change(a0, lim >> 1) a1 = self.FFt_change(a1, lim >> 1) return a0 + a1 迭代 fft def FFT_high(self, fs, time): # 迭代的 FFT resolution = fs * time # 计算出总共的点数 fre = 1 t = np.arange(0.0, time, (time / resolution)) # 时域的 t 轴 s = 2 * np.cos(2 * np.pi * t * fre) # 自己定义的一个时域的函数 一个幅值为 2 频率为 fre 的 cos 函数 a = s[:] lim = resolution a = self.FFt_change(a, lim) # 对时域的数据排序 f = [] # 将排序好的数据进行复数部分补零 for i in range(0, resolution): f_cache = [a[i], 0] f.append(f_cache) print(f) for dep in range(0, int(np.log2(lim))): # 迭代的 FFT 算法 m = 1 << (dep+1) wn = [np.cos(2 * np.pi / m), np.sin(2 * np.pi / m)] for k in range(0, lim, m): w = [1, 0] for j in range(0, int(m/2)): x = self.Ploral_Mul(w, f[int(k + j + m / 2)]) u = f[k + j] f[k + j] = self.Ploral_Add(u, x) f[int(k + j + m / 2)] = self.Ploral_Sub(u, x) w = self.Ploral_Mul(w, wn) f_show = [] # 将算出来的数据 a+bi 进行 c = a*a + b*b ,再对 c 开方, 并存入一个列表 用于显 示频域的图像 for i in range(0, resolution): f_show.append(np.sqrt(f[i][0] * f[i][0] + f[i][1] * f[i][1])) self.F.axes1 = self.F.fig.add_subplot(121) # 创建图像显示 self.F.axes1.plot(t, s) self.F.axes1.set_title('Time') self.F.axes2 = self.F.fig.add_subplot(222) self.F.axes2.scatter(t, f_show)
self.F.axes2.set_title('Frequency_cos') f_cos_child = f_show[0:int(resolution/2)] # 计算频率 f_cos_index = f_cos_child.index(max(f_cos_child)) print('f_cos 频率是', f_cos_index * fs / resolution) 5.系统运行 离散型快速傅里叶变换: 较低采样频率时:
较高采样频率时: 6.总结
分享到:
收藏