当前位置: 首页 > news >正文

关于利用FFT分析时域信号幅相的思考与验证



引言

利用FFT分析/估计时域信号的幅度和相位,属于传统估计的范畴。估计的准确程度受频率分辨率的影响较大。如果被估计的目标频率等于频率分辨率的整数倍,信号的幅相估计都是最准确的。一旦目标频率不等于频率分辨率的整数倍,幅度估计值将会降低,相位估计值会偏差很大。

下面会通过一些仿真来验证。

单点频实信号估计

信号幅值:10

信号相位:45°

信号频率:100Hz

信号类型:实信号

采样率:1000Hz

采样点数:100

频率分辨率:10Hz

信号频率等于分辨率整数倍

MATLAB代码:

clc;
clearvars;
close all;fs=10e2;
f0=1e2;
p0=-pi/8;
N=100;
t=(0:N-1)/fs;
s=10*cos(2*pi*f0*t+p0);
figure;
subplot(311)
plot(s)
title('时域波形');xlabel('采样点数');ylabel('采样幅度')subplot(312)
plot((linspace(-fs/2,fs/2-fs/N,N)),abs(fftshift(fft(s)))/N)
title('幅度谱');xlabel('频率/Hz');ylabel('幅度')subplot(313)
plot((linspace(-fs/2,fs/2-fs/N,N)),angle(fftshift(fft(s)))/pi*180)
title('相位谱');xlabel('频率/Hz');ylabel('相位/°')

 注意,此处分析的双边谱,所以每边高度为 10/2 = 5;

相位估计很准确,是45°相位。

信号频率不等于分辨率整数倍

如果改变采样点数(改为128),使得频率分辨率变化,不等于分辨率的整数倍,则:

clc;
clearvars;
close all;fs=10e2;
f0=1e2;
p0=pi/4;
N=128;
t=(0:N-1)/fs;
s=10*cos(2*pi*f0*t+p0);
figure;
subplot(311)
plot(s)
title('时域波形');xlabel('采样点数');ylabel('采样幅度')subplot(312)
plot((linspace(-fs/2,fs/2-fs/N,N)),abs(fftshift(fft(s)))/N)
title('幅度谱');xlabel('频率/Hz');ylabel('幅度')subplot(313)
plot((linspace(-fs/2,fs/2-fs/N,N)),angle(fftshift(fft(s)))/pi*180)
title('相位谱');xlabel('频率/Hz');ylabel('相位/°')

 根据仿真结果,发现频率、幅度估值有微小偏差,相位的估计值几乎不可信

信号频率等于分辨率整数倍,加噪声

考虑噪声影响:

clc;
clearvars;
close all;fs=10e2;
f0=1e2;
p0=pi/4;
N=100;
t=(0:N-1)/fs;
s=10*cos(2*pi*f0*t+p0) + 2*randn(1,N);
figure;
subplot(311)
plot(s)
title('时域波形');xlabel('采样点数');ylabel('采样幅度')subplot(312)
plot((linspace(-fs/2,fs/2-fs/N,N)),abs(fftshift(fft(s)))/N)
title('幅度谱');xlabel('频率/Hz');ylabel('幅度')subplot(313)
plot((linspace(-fs/2,fs/2-fs/N,N)),angle(fftshift(fft(s)))/pi*180)
title('相位谱');xlabel('频率/Hz');ylabel('相位/°')

 根据仿真结果,信号的频率估计准确,但是幅度和相位的估计存在微小误差。

多点频实信号估计

信号的频点均位于频率分辨率整数倍的位置:

clc;
clearvars;
close all;fs=10e2;
f0=1e2;
p0=pi/4;
f1=2e2;
p1=pi/2;
N=100;
t=(0:N-1)/fs;
s=10*cos(2*pi*f0*t+p0) + 4*cos(2*pi*f1*t+p1);
figure;
subplot(311)
plot(s)
title('时域波形');xlabel('采样点数');ylabel('采样幅度')subplot(312)
plot((linspace(-fs/2,fs/2-fs/N,N)),abs(fftshift(fft(s)))/N)
title('幅度谱');xlabel('频率/Hz');ylabel('幅度')subplot(313)
plot((linspace(-fs/2,fs/2-fs/N,N)),angle(fftshift(fft(s)))/pi*180)
title('相位谱');xlabel('频率/Hz');ylabel('相位/°')

对于多点频信号,只要信号频点均位于分辨率整数倍的位置,其估值都十分准确。

多点频复信号估计

下面再试验一下复信号:

clc;
clearvars;
close all;fs=10e2;
f0=1e2;
p0=pi/4;
f1=2e2;
p1=pi/2;
N=100;
t=(0:N-1)/fs;
s=10*exp(1j*(2*pi*f0*t+p0)) + 4*exp(1j*(2*pi*f1*t+p1));
figure;
subplot(411)
plot(real(s))
title('时域波形(实部)');xlabel('采样点数');ylabel('采样幅度')subplot(412)
plot(imag(s))
title('时域波形(虚部)');xlabel('采样点数');ylabel('采样幅度')subplot(413)
plot((linspace(-fs/2,fs/2-fs/N,N)),abs(fftshift(fft(s)))/N)
title('幅度谱');xlabel('频率/Hz');ylabel('幅度')subplot(414)
plot((linspace(-fs/2,fs/2-fs/N,N)),angle(fftshift(fft(s)))/pi*180)
title('相位谱');xlabel('频率/Hz');ylabel('相位/°')

 根据仿真结果,可以看出,复信号同样满足上述结论,即信号频率位于分辨率整数倍位置时,用FFT可以精确估计其频率和相位。

结论

结尾处再次说明一下:

不论是是信号还是复信号:

  1. 不加噪声时,位于分辨率整数倍处的信号频率、相位均可以被精确估算;
  2. 不加噪声时,不位于分辨率整数倍处的信号频率的估计存在微小误差、相位估计值基本不可信
  3. 加噪声时,位于分辨率整数倍处的信号频率可以被精确估算,相位估算存在微小偏差;

可以结合代码和仿真进行理解,如有疑问,评论区留言吧~~

相关文章:

关于利用FFT分析时域信号幅相的思考与验证

引言 利用FFT分析/估计时域信号的幅度和相位,属于传统估计的范畴。估计的准确程度受频率分辨率的影响较大。如果被估计的目标频率等于频率分辨率的整数倍,信号的幅相估计都是最准确的。一旦目标频率不等于频率分辨率的整数倍,幅度估计值将会…...

基于java中的Springboot框架实现餐厅点餐系统展示

基于java中的Springboot框架实现餐厅点餐系统开发语言和工具 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 21世纪的今天,随着社会的不断发展与进步,人们对…...

案例07-在线人员列表逻辑混乱

一、背景介绍 在线人员列表涉及到的问题: 类中写了公共变量最后导致数据混乱现象 保存数据没有考虑业务的隔夜覆盖导致的逻辑漏洞 涉及到继承,对于this,如果父类有同样的成员最终使用哪一个? 参数不一致导致后续维护混乱 mysql由…...

Java集合框架

Java集合框架是Java编程语言所提供的一种便捷的数据结构的实现。Java集合框架提供了一种统一的接口和机制来访问和操作集合中的元素,这些元素可以是对象、基本数据类型或其他集合。Java集合框架是Java应用程序中最常用的特性之一,它为开发人员提供了许多…...

奇异值分解(SVD)原理与在降维中的应用

奇异值分解(SVD)原理与在降维中的应用 奇异值分解(Singular Value Decomposition,以下简称SVD)是在机器学习领域广泛应用的算法,它不光可以用于降维算法中的特征分解,还可以用于推荐系统,以及自然语言处理等领域。是很多机器学习算…...

GDB调试程序

1.GDB 调试程序 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。在UNIX平台下做软件,GDB这个调试工具有比VC的图形化调试器更强大的功能。所谓“寸有所长,尺有所短”就是这个道理。 一般来说,GDB主要帮忙你完成下面四个方面的功能…...

五种IO模型

用户空间与内核空间 操作系统把内存空间划分成了两个部分:内核空间和用户空间。 为了保护内核空间的安全,操作系统一般都限制用户进程直接操作内核。 所以,当我们使用TCP发送数据的时候,需要先将数据从用户空间拷贝到内核空间&a…...

5 全面认识java的控制流程

全面认识java控制流程1.块作用域2.条件语句3.迭代语句3.1while语句3.2do-while语句3.3for语句3.4 for-in语法4.中断控制流程的语句4.1 return4.2 break和continue4.2.1 不带标签的break语句4.2.2 带标签的break语句4.2.3 continue语句4.3 goto()5.多重选择:switch语句1.块作用域…...

第二章 测验【嵌入式系统】

第二章 测验【嵌入式系统】前言推荐第二章 测验【嵌入式系统】最后前言 以下内容源自《嵌入式系统》 仅供学习交流使用 推荐 第一章 测验【嵌入式系统】 第二章 测验【嵌入式系统】 1单选题 32bit宽的数据0x12345678 在小端模式(Little-endian)模式…...

排序算法之插入排序

要考数据结构了,赶紧来复习一波排序算法 文章目录一、直接插入排序二、希尔排序一、直接插入排序 直接上主题 插排,揪出一个数,插入到原本已经有序的数组里面,如数组有n个数据,从0~n下标依次排列,先从左往…...

Kaggle实战入门:泰坦尼克号生生还预测

Kaggle实战入门:泰坦尼克号生生还预测1. 加载数据2. 特征工程3. 模型训练4. 模型部署泰坦尼克号(Titanic),又称铁达尼号,是当时世界上体积最庞大、内部设施最豪华的客运轮船,有“永不沉没”的美誉&#xff…...

【大汇总】11个Python开发经典错误(1)

“但是太阳,他每时每刻都是夕阳也都是旭日。当他熄灭着走下山去收尽苍凉残照之际,正是他在另一面燃烧着爬上山巅散烈烈朝晖之时。” --------史铁生《我与地坛》 🎯作者主页:追光者♂🔥 🌸个人简介:计算机专业硕士研究生💖、2022年CSDN博客之星人工智能领…...

Java中的异常

程序错误一般分为三种:编译错误: 编写程序时没有遵循语法规则,编译程序能够自己发现错误并提示位置和原因。运行错误:程序在执行的时候运行环境发现了不能执行的操作。比如,JVM出错了,内存溢出等。逻辑错误…...

L2-022 重排链表 L2-002 链表去重

给定一个单链表 L1 →L2→⋯→L n−1 →L n ,请编写程序将链表重新排列为 L n →L 1 →L n−1 →L 2 →⋯。例如:给定L为1→2→3→4→5→6,则输出应该为6→1→5→2→4→3。 输入格式: 每个输入包含1个测试用例。每个测试用例第1行…...

【手撕八大排序】——插入排序

文章目录插入排序概念插入排序分为2种一 .直接插入排序直接插入排序时间复杂度二.希尔排序希尔排序时间复杂度效率比较插入排序概念 直接插入排序是从一个有序的序列中选择一个合适的位置进行插入,这个合适的位置取决于是要升序排序还是降序排序。 每一次进行排序…...

flink多流操作(connect cogroup union broadcast)

flink多流操作1 分流操作2 connect连接操作2.1 connect 连接(DataStream,DataStream→ConnectedStreams)2.2 coMap(ConnectedStreams → DataStream)2.3 coFlatMap(ConnectedStreams → DataStream)3 union操作3.1 uni…...

漫画:什么是快速排序算法?

这篇文章,以对话的方式,详细着讲解了快速排序以及排序排序的一些优化。 一禅:归并排序是一种基于分治思想的排序,处理的时候可以采取递归的方式来处理子问题。我弄个例子吧,好理解点。例如对于这个数组arr[] { 4&…...

vue 3.0组件(下)

文章目录前言:一,透传属性和事件1. 如何“透传属性和事件”2.如何禁止“透传属性和事件”3.多根元素的“透传属性和事件”4. 访问“透传属性和事件”二,插槽1. 什么是插槽2. 具名插槽3. 作用域插槽三,单文件组件CSS功能1. 组件作用…...

双指针 -876. 链表的中间结点-leetcode

开始一个专栏,写自己的博客 双指针,也算是作为自己的笔记吧! 双指针从广义上来说,是指用两个变量在线性结构上遍历而解决的问题。狭义上说, 对于数组,指两个变量在数组上相向移动解决的问题;对…...

Linux之运行级别

文章目录一、指定运行级别基本介绍CentOS7后运行级别说明一、指定运行级别 基本介绍 运行级别说明: 0:关机 1:单用户【找回丢失密码】 2:多用户状态没有网络服务 3:多用户状态有网络服务 4:系统未使用保留给用户 5:图形界面 6:系统重启 常用运行级别是3和5,也可以…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

ip子接口配置及删除

配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

【生成模型】视频生成论文调研

工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...