Matlab中cpsd与pspectrum的差异:功率谱密度与功率谱的困惑
为什么Matlab中cpsd和pspectrum的频谱结果差异极大?
核心原因:两者的输出定义与计算参数默认值完全不同
物理量定义差异
cpsd直接输出功率谱密度(PSD),单位是dB/Hz,代表单位频率范围内的功率;pspectrum默认输出功率谱(PS),单位是dB,代表每个离散频率点上的总功率(等于PSD乘以该点的频率分辨率Δf)。
两者不是简单的归一化关系,数值差由频率分辨率决定,但默认参数下Δf不一致,导致曲线差异显著。
计算参数默认值不同
cpsd默认采用Welch方法,使用Hann窗、50%重叠,FFT长度取max(256, nextpow2(N))(N为信号长度);pspectrum默认的计算逻辑(未指定方法时)会根据信号自动选择分段、窗函数和FFT长度,和cpsd的默认参数不匹配,进一步放大了结果差异。
代码中的绘图细节问题
你把pspectrum的线性频率f转成角频率2πf是对的,但功率值的单位未统一:10*log10(p1)是PSD的dB/Hz,而pow2db(p2)是PS的dB,两者的物理量本身不同,直接对比自然差异大。
统一参数后的对比方法
要让两者结果一致,需要强制使用相同的计算参数,并统一物理量单位:
Ts = 0.01; Fs = 1/Ts; u = [ones(100, 1); zeros(200,1); ones(500,1); zeros(800,1)]-1; t = (0:length(u)-1)'*Ts; % 统一计算参数:Hann窗、256点FFT、50%重叠 win = hann(256); nfft = 256; noverlap = 128; % cpsd计算PSD [p1,w] = cpsd(u,u,win,noverlap,nfft,Fs); psd_cpsd = 10*log10(p1); % pspectrum计算后转成PSD(默认输出是PS,需除以频率分辨率Δf) [p2,f] = pspectrum(u,t,'Welch','Window',win,'OverlapLength',noverlap,'FFTLength',nfft); delta_f = Fs/nfft; psd_pspectrum = pow2db(p2 / delta_f); % 对比绘图 figure; semilogx(w, psd_cpsd, 'b-', 'LineWidth',1.5); hold on; semilogx(2*pi*f, psd_pspectrum, 'r--', 'LineWidth',1.5); legend('cpsd (PSD)', 'pspectrum (转PSD)'); xlabel('角频率 (rad/s)'); ylabel('功率谱密度 (dB/Hz)'); hold off;
运行这段代码后,两条曲线会基本重合,说明参数统一后两者的计算逻辑是一致的。
额外提示
你代码里的测试信号是阶跃组合,不是PRBS信号。如果分析PRBS,记得生成标准的PRBS序列(用prbs函数)后再做频谱分析,结果会更符合预期。
内容的提问来源于stack exchange,提问作者Jean-Fr




