(45)MATLAB计算信号的幅度谱与相位谱

文章目录


前言

信号的频谱分析包括信号的幅度谱和相位谱,其中幅度谱是组成信号的各频谱成分的幅度,相位谱是组成信号的各频谱成分的初始相位。本文给出使用MATLAB计算信号幅度谱和相位谱的方法。特别指出在计算信号相位谱的时候,要避免相位信息误差导致不能得到正确的相位谱的问题。


一、MATLAB代码

幅度谱前面已经详细介绍过了。可以参见以下文章:
(34)FFT与信号频谱(双边谱)
(35)信号频谱的双边谱与单边谱
(36)高分辨率频谱------通过在时域序列后面补零提高频域分辨率
(37)使用MATLAB画出余弦波的频谱
(38)MATLAB分析带噪信号的频谱
(42)MATLAB中使用fftshift绘制以零为中心的功率谱

本文重点分析相位谱。相位谱的计算公式如下:

计算信号幅度谱和相位谱的MATLAB代码如下:

c 复制代码
%% 生成时域信号
f1 = 10;                       % 余弦波1的频率,单位Hz
f2 = 20;                       % 余弦波2的频率,单位Hz
p1 = 30;                       % 余弦波1的初始相位,单位度
p2 = 45;                       % 余弦波2的初始相位,单位度
A1 = 0.5;                      % 余弦波的振幅
A2 = 1;                        % 余弦波的振幅
fs = 320;                     % 采样率                   
Ts = 1/fs;                     % 采样时间间隔    
t  =0:1/fs:2-1/fs;             % 信号时长2秒

s1 = A1*cos(2*pi*f1*t + p1*pi/180);  % 信号1
s2 = A2*cos(2*pi*f2*t + p2*pi/180);  % 信号2
x = s1 + s2;                         % 和信号

figure()
subplot(2,2,1);
plot(t,x);
grid on;
title('time domain signal');
xlabel('t/s');
ylabel('x(t)');
ylim([-1.5 2])
%% 频域分析:幅度谱与相位谱
N = 512;                           % FFT size
X = 1/N*fftshift(fft(x,N));        % N-point complex DFT

df = fs/N;                         % 频率分辨率
n = -N/2:N/2-1;                    % FFT结果序号
f = n*df;                          % x轴索引转换为频率值
subplot(2,2,2);
plot(f,abs(X));                    % 幅度谱
grid on;
title('Magnitude spectrum');
xlabel('f (Hz)');
ylabel('|X(k)|');
xlim([-100 100])

% 直接计算相位谱
phase = atan2(imag(X),real(X))*180/pi;    % 原始相位信息是被计算误差污染的
subplot(2,2,3);
plot(f,phase);                            % 相位谱
grid on;
title('Phase spectrum (noisy)');
xlabel('f(Hz)');
ylabel('angle(X(k))');
xlim([-100 100])

二、仿真结果画图

信号的时域波形图:

信号的双边幅度谱:

信号的相位谱:

【相位谱分析】

从这个相位谱可以发现,相位信息误差导致不能得到正确的相位谱。

这个相位谱充满了噪声,几乎不能得出有效的相位信息。相位谱之所以噪声很大,是因为相位谱是通过计算FFT结果的虚部与实部之比的反正切得到的。这样,即使是微小的浮点舍入误差也会放大结果,并以相位信息的形式错误地表现出来。为了理解这一点,可以打印出FFT结果的前几个样本,可以发现它们并不完全等于0(虽然理论上应该等于0,但实际上所得到的值是非常小的数值,大约在10^-16的量级)。计算反正切将导致不正确的结果。

解决方案是定义一个容差阈值,所有低于阈值的计算相位都将被忽略。下面给出正确的相位谱计算方法。

三、正确的相位谱计算方法与仿真结果

1.MATLAB代码

正确的相位谱计算的MATLAB代码如下::

c 复制代码
% 排除信号误差对相位谱的影响
X2 = X;
threshold = max(abs(X))/10000;            % 设置误差门限
X2(abs(X)<threshold) = 0;                 % 小于门限的值清零
phase = atan2(imag(X2),real(X2))*180/pi;  % 提取相位信息
subplot(2,2,4);
plot(f,phase);                            % 相位谱
grid on;
title('Phase spectrum');
xlabel('f(Hz)');
ylabel('angle(X(k))');
xlim([-100 100])

2.正确的相位谱

所得到的相位谱如下:


分析:
正确的相位谱指出在频率f = 10Hz处的30°相位偏移,和在频率f = 20Hz处的45°相位偏移。相位谱是反对称的:在f = −10Hz处φ = −30°,在f = −20Hz处φ = −45°,这个仿真结果完全符合实值信号的理论分析。


相关推荐
ゞ 正在缓冲99%…11 分钟前
leetcode76.最小覆盖子串
java·算法·leetcode·字符串·双指针·滑动窗口
xuanjiong11 分钟前
纯个人整理,蓝桥杯使用的算法模板day2(0-1背包问题),手打个人理解注释,超全面,且均已验证成功(附带详细手写“模拟流程图”,全网首个
算法·蓝桥杯·动态规划
惊鸿.Jh30 分钟前
【滑动窗口】3254. 长度为 K 的子数组的能量值 I
数据结构·算法·leetcode
明灯L31 分钟前
《函数基础与内存机制深度剖析:从 return 语句到各类经典编程题详解》
经验分享·python·算法·链表·经典例题
碳基学AI37 分钟前
哈尔滨工业大学DeepSeek公开课:探索大模型原理、技术与应用从GPT到DeepSeek|附视频与讲义免费下载方法
大数据·人工智能·python·gpt·算法·语言模型·集成学习
补三补四40 分钟前
机器学习-聚类分析算法
人工智能·深度学习·算法·机器学习
独好紫罗兰1 小时前
洛谷题单3-P5718 【深基4.例2】找最小值-python-流程图重构
开发语言·python·算法
正脉科工 CAE仿真1 小时前
基于ANSYS 概率设计和APDL编程的结构可靠性设计分析
人工智能·python·算法
Dovis(誓平步青云)1 小时前
【数据结构】排序算法(中篇)·处理大数据的精妙
c语言·数据结构·算法·排序算法·学习方法
2401_872945092 小时前
【补题】Xi‘an Invitational 2023 E. Merge the Rectangles
算法