☰
三频正弦DFT频谱分析:补零加窗与重叠相加保留
2026/10/26 17:16:28 网站建设 项目流程

简介:面向数字信号处理课程学习与课程大作业场景,这份文档围绕“利用DFT分析信号频谱”展开,适合电子信息工程等专业学生梳理离散傅里叶变换的核心概念与MATLAB实验流程。压缩包共1个docx文件,约1.53MB,内容按问题描述、原理与方法、结果与讨论、结论与启示、附录程序组织,结构完整,便于直接查阅、对照和仿写。文档从DFT与DTFT的关系切入,说明频率分辨率与采样频率、数据长度的联系,并结合多正弦离散信号和连续时间信号案例,分析采样点数、采样频率、补零和加窗对频谱混叠、栅栏效应、频谱泄漏及分辨率的影响。附录给出MATLAB fft实现代码,可用于实验复现、课程报告撰写和知识点查漏补缺。已有1248人学习下载,适合作为数字信号处理作业参考与复习材料。

1. 三频正弦叠在一起,FFT 出来的谱为什么认不出三个峰

数字信号处理课里有一份很典型的 DFT 频谱分析大作业:给一段由三个正弦叠加的离散序列,让你用 FFT 把它拆开,再拿采样长度、补零、加窗三样东西反复试,最后说清楚频率分辨率到底被什么决定。事情听起来简单,第一版跑出来经常翻车——明明三个分量,N 取 8 时谱上只剩两根柱子,取 16 时多出一堆毛刺,取 32 才干净。这份资源把离散信号频谱分析、连续时间信号采样、重叠相加与重叠保留算长序列线性卷积四块串在一起,配套两份可直接运行的 MATLAB 脚本和一份完整结果讨论。它适合正在做大作业、课程设计,或者需要拿 MATLAB 快速验证一段信号谱的人:改三个参数,谱形怎么变,一眼就能看到。

2. 把 DTFT、DFT、频率分辨率落到坐标轴上:k、fs、N 三个数怎么摆

动手之前必须把三件事钉死:DFT 的第 k 根谱线对应哪个频率、分辨率由谁决定、补零到底改变了什么。这三个问题答错任何一个,后面所有的图都是错的,而且错得不明显——图能画出来,长得还挺像,只有拿理论位置去对才发现偏了。

2.1 DFT 是 DTFT 在单位圆上的等间隔采样

离散时间傅里叶变换的定义是 X(e^{jω}) = Σ x(n)·e^{-jωn},ω 是连续取值的,画出来是一条连续曲线。DFT 只在这个单位圆上取 N 个等分点:

X(k) = Σ_{n=0}^{N-1} x(n)·e^{-j2πkn/N},k = 0, 1, …, N-1

两者之间就是采样关系:X(k) = X(e^{jω}) 在 ω = 2πk/N 处的取值。所以第 k 根谱线对应的归一化数字频率是 2k/N(单位是 π),对应的模拟频率是 f_k = k·fs/N。0 到 N-1 的全段里,前一半是正频率,后一半是负频率,实信号两边共轭对称,实际只画 0 到 N/2 就够。

这一条直接决定了绘图时横轴写什么。原脚本里写n*2/N作为横轴,本质就是把 k 换成 ω/π,因为 ω_k/π = 2k/N。如果换成了 k/N,整张图的频率刻度就缩了一半,理论峰位全部对不上——这是最高频的一类错误,因为图看着是正常的。

2.2 分辨率 F = fs/N 的两种误读

频率分辨率 F = fs/N,也可以用记录长度表示:N·Ts = T,所以 F = 1/T。分辨率的物理含义是「能区分开的最小频率间隔」,它由观察窗口的时间长度决定,跟你在窗口里插了多少个计算点没关系。

补零常被误读成「提高分辨率」。补零做的事是在已有的 DTFT 采样点之间插入更多采样点,谱线变密、包络更光滑,但主瓣宽度一点没变,两个靠得近的频率仍然糊在一起。用信号处理的说法,补零是频域插值,不是频域分辨率提升。真正提升分辨率的只有一条路:把真实记录时间拉长,多采一些有效数据,而不是多补一些零。

实操上判断「能不能分开」有个粗略判据:两个峰的间隔 Δf 至少要大于主瓣宽度。矩形窗的主瓣宽度约为 2/T,也就是 2F;换成汉宁窗、海明窗这类,主瓣还会再宽一倍。所以算出来 F = 0.1 Hz 不代表间隔 0.1 Hz 的两个峰就能分开,保守要留 2 到 4 倍余量。

2.3 三类误差:混叠、栅栏、泄漏

误差类型产生原因现象主要对策
频谱混叠采样率低于信号最高频率的 2 倍高频分量折叠到低频,谱形错乱且无法事后修复提高 fs,或前置抗混叠滤波
栅栏效应DFT 只给 N 个离散样本,样本之间未知峰值落在两根谱线中间时幅度被压低增加记录长度;补零只能让包络更好看
频谱泄漏时域截断等效乘矩形窗,窗谱被卷积进信号谱单根谱线向两侧拖尾,弱分量被强分量的旁瓣淹没换旁瓣更低的窗;整周期截断

这三类误差里,混叠是唯一不可逆的——一旦折叠进来,后面无论怎么补零、加窗都救不回来,属于没有后悔药的那一种。泄漏和栅栏效应只是精度损失,可以通过参数调整改善。

2.4 一个通用的频谱计算函数

把归一化、单边谱、频率轴三件事封到一个函数里,后面所有实验都复用它,避免每换一个信号就重写一遍横轴。

function [X, w, f] = dft_spectrum(x, fs, fftlen) %DFT_SPECTRUM 计算实序列的单边幅度谱 % x 输入序列,行/列均可 % fs 采样频率 % fftlen FFT 点数,大于 length(x) 时等效于末端补零 x = x(:).'; % 统一成行向量,规避后面的转置坑 N = length(x); % 真实记录长度,决定分辨率 if nargin < 3 || isempty(fftlen) fftlen = N; end M = max(fftlen, N); % 补零后的计算点数,只影响谱线密度 X = fft(x, M); k = 0:M-1; w = 2*k/M; % 归一化数字频率 ω/π f = k*fs/M; % 对应模拟频率 half = floor(M/2); X = X(1:half+1) * 2 / N; % 单边谱,幅度按真实长度 N 归一 X(1) = X(1)/2; % 直流分量不乘 2 w = w(1:half+1); f = f(1:half+1); end

关键在倒数第四行:归一化除的是真实长度N,不是补零后的M。补零不增加非零样本个数,FFT 结果的幅度值本身不变,如果按M去归一,补的零越多幅度谱整体越矮,画出来的图会一路往下缩,看着像信号能量丢了,其实只是标定错了。X(1) = X(1)/2是因为单边谱把负频率能量折到正频率时统一乘了 2,直流那一根没有对应的负频率搭档,要单独还原。

3. 离散三频信号实测:N 从 8 到 32 与补零对照

理论摆完就上手。这一章用一个已知答案的信号做对照实验:三个频率分量、幅度各不相同,理论谱形可以手算出来,跑完直接对位置和幅度,错在哪一目了然。

3.1 信号构造与参数设定

信号取自资源里的离散序列:

% exp3_discrete_dft.m 三个正弦叠加信号的 DFT 频谱分析 clear; clc; N = 32; % 采样点数,对照实验改成 8 / 16 / 32 n = 0:N-1; x = 0.15*sin(2*pi*n/32) + sin(8*pi*n/32) - 0.1*sin(16*pi*n/32); [X, w, f] = dft_spectrum(x, 1, N); % fs 取 1,横轴直接读归一化频率 subplot(3,1,1); stem(n, x, 'filled'); grid on; xlabel('n'); ylabel('x(n)'); title(['时域波形 N=' num2str(N)]); subplot(3,1,2); plot(w, abs(X)); grid on; xlabel('\omega/\pi'); ylabel('|X|'); title('DFT 幅度谱(连线看包络)'); subplot(3,1,3); stem(w, abs(X), 'filled'); grid on; xlabel('\omega/\pi'); ylabel('|X|'); title('DFT 幅度谱(实际谱线)');

三个分量分别是 ω1 = π/16(幅度 0.15)、ω2 = π/4(幅度 1)、ω3 = π/2(幅度 0.1)。第二分量最强,第一分量最弱且离得最近,是最容易被旁瓣吃掉的那一个。画两组图有讲究:连线能看清包络和泄漏的形状,stem 能看清到底落在哪几根谱线上,只画一种容易误判。

3.2 N=8 为什么分不开 π/16 与 π/4

N = 8 时谱线间隔是 2π/8 = π/4。ω2 恰好落在 k=1、ω3 恰好落在 k=2,都是整格点;但 ω1 = π/16 只相当于 0.25 根谱线,落在 k=0 和 k=1 的正中间,能量被摊到两根谱线上,还会跟 ω2 的泄漏混在一起。结果就是谱上看到的是两个鼓包,第一个鼓包是 ω1 和 ω2 的混合体,没法判断里面到底有几个频率。

N谱线间隔 Δω折合模拟频率(fs=1)ω1=π/16 落在ω2=π/4 落在能否分开 ω1 与 ω2
8π/40.125k=0.25(不落格点)k=1否
16π/80.0625k=0.5(不落格点)k=2勉强,靠包络猜
32π/160.03125k=1(落格点)k=4是

N = 32 之所以干净,还有一个更本质的原因:三个分量的周期分别是 32、8、4 个采样点,N = 32 正好是它们的最小公倍数。整周期截断意味着截断处首尾能接上,等效于没有截断,泄漏为零,谱线只落在 k=1、4、8 三根上,其余位置是干净的零。这是工程上非常实用的经验——只要可能,就把记录长度凑成信号基频周期的整数倍,泄漏问题从源头上就没了。

3.3 补零 1/2/3 倍:谱线变密,分辨率不变

补零的对照实验如下,注意原始长度要单独存一个变量,不能让新长度把旧长度覆盖掉:

M = length(x); % 原始点数,单独保存,后面反复用 w0 = 2*(0:M-1)/M; figure('Name','补零对照'); for pad = 0:3 y = [x zeros(1, pad*M)]; % 末端补 pad 倍零 L = length(y); Y = fft(y) * 2 / M; % 归一化仍按真实长度 M Y = Y(1:floor(L/2)+1); wk = 2*(0:floor(L/2))/L; subplot(4,1,pad+1); stem(wk, abs(Y), 'filled'); grid on; xlabel('\omega/\pi'); ylabel('|Y|'); title(['原始 ' num2str(M) ' 点,末端补 ' num2str(pad) ' 倍零,谱线数 ' num2str(L)]); end

跑完会看到一个很明确的现象:补零倍数越大,谱线越密,曲线越光滑,但三个鼓包的宽度一点没变,原本糊在一起的两个峰补完零还是糊在一起。补零后的图本质上就是对原序列 DTFT 的更密采样,把原来「看不见的中间值」画出来了,信息量并没有增加。

这里有个容易忽略的细节:循环里用了变量名L存补零后的长度,如果前面已经用L表示过别的长度(比如卷积里的分块长度),就会在后面莫名其妙出错。原脚本用N = N*2直接覆盖采样点数,属于同一类隐患——一旦覆盖,后面想再算分辨率 F = fs/N 就已经拿不到真实的 N 了,只能得到一个偏小几倍的分辨率,结论直接反了。

4. 加窗与连续信号采样:泄漏、混叠、高频容量的三方权衡

离散信号那部分是「已知答案对答案」,连续信号这部分难度上一个台阶:信号本身是无限长的,采样和截断都是近似,谱形对不对没有唯一标准,只能看趋势合不合理。加窗也放在这一章一起说,因为它和截断是同一件事的两面。

4.1 三角窗、汉宁窗、海明窗的对比与转置

对比四种窗,统一在一张图上画,方便看主瓣和旁瓣的差别:

M = length(x); winList = {'矩形窗', ones(1,M); ... '三角窗', triang(M)'; ... % 转置!否则是列向量 '汉宁窗', hanning(M)'; ... '海明窗', hamming(M)'}; figure('Name','加窗对比'); for i = 1:size(winList,1) wv = winList{i,2}; % 已经是 1×M 行向量 y = x .* wv; Y = fft(y) * 2 / sum(wv); % 按窗能量归一,便于比较幅度 Y = Y(1:floor(M/2)+1); subplot(4,1,i); stem(2*(0:floor(M/2))/M, abs(Y), 'filled'); grid on; xlabel('\omega/\pi'); ylabel('|Y|'); title([winList{i,1} ' N=' num2str(M)]); end

triang、hanning、hamming这三个函数返回的都是列向量(M×1)。如果直接写x .* hanning(M),MATLAB 会触发隐式扩展,把 1×M 的行向量和 M×1 的列向量相乘,得到一个 M×M 的矩阵,接着fft对矩阵按列做变换,画出来是一整片五颜六色的图。这个坑在原作业的记录里被专门点过名,属于血泪经验级别的存在。

窗的选取按主瓣宽度和旁瓣高度的权衡来:

窗类型主瓣宽度(相对 2π/N)最高旁瓣适用场景
矩形窗2-13 dB分辨率优先,整周期截断时首选
三角窗4-27 dB折中方案,实现简单
汉宁窗4-31 dB通用频谱分析,泄漏和分辨率平衡
海明窗4-43 dB强分量旁边有弱分量,需要压近端泄漏

主瓣宽了,能分辨的最小间隔就变大,等同于分辨率下降。所以在 N 已经够大、谱线本来就分得开的时候加窗,收益很小、代价却实打实:主瓣展宽,原本分开的两个峰反而开始互相污染。原作业里那句「N=32 时再加窗反而使频谱发生混淆」,说的就是这个现象。

还有一个反直觉的结论值得单独记:对信号做截断,本身就已经加了一次矩形窗。已经截断的序列再去乘别的窗,等效于矩形窗频谱和该窗频谱做卷积,泄漏并不会因为「多加一个窗」而消失,只是换了一种形状。要真正减少泄漏,要么整周期截断,要么在接受主瓣展宽的前提下选旁瓣低的窗。

4.2 连续信号 exp(-0.1t)·u(t) 的采样

连续信号分析用的是指数衰减信号,脚本里的写法需要改一处:

N = 100; % 采样点数 fs = 0.01; % 采样频率,对照时改成 1 / 0.1 / 0.01 n = 0:N-1; t = n / fs; x = exp(-0.1*t) .* (t >= 0); % 用逻辑索引代替 heaviside

原脚本写的是heaviside(n/fs),MATLAB 的heaviside(0)返回 0.5,第一个采样点被砍掉一半幅度,相当于在序列头部人为制造了一个跳变,频谱里会多出一份本不该有的高频成分。换成(t >= 0)之后,t=0 处取值明确为 1,边界干净,谱形更接近理论值 1/(0.1 + j2πf)。这类「库函数默认约定」的细节就是黑匣子,不查文档根本看不出问题,图也能画出来,只是怎么调都对不上理论曲线。

4.3 高频容量与分辨率的矛盾

参数扫描的结果整理成表:

Nfs记录长度 T = N/fs分辨率 F = fs/N可观测最高频率 fs/2
101100.10.5
201200.050.5
200.12000.0050.05
1000.110000.0010.05
1000.01100000.00010.005

读这张表能读出三条结论。第一,N 不变、fs 降低,分辨率和可观测带宽同时变化,而且方向相反:fs 从 1 降到 0.1,分辨率从 0.05 提升到 0.005,可观测带宽却从 0.5 掉到 0.05,这就是所谓「高频容量与频率分辨率不可兼得」。第二,fs 不变、N 增加,分辨率提升而可观测带宽不变,这是最安全的做法,代价是记录时间变长、数据量变大。第三,要想两个指标同时改善,唯一的办法是拉长记录时间 T,因为 F = 1/T、fs 上限也由采集条件决定,只有 T 是能自由加长的。

具体到这个信号,衰减因子 0.1 对应极点频率约 0.016 Hz,能量主要集中在 0.05 以内。所以 fs = 0.1 时刚好覆盖主要能量,谱形可信;fs = 0.01 时可观测上限只有 0.005,主要能量被切在外面折了回来,虽然分辨率数字很好看(0.0001),谱形其实已经混叠失真。看见「分辨率很高但曲线形状怪」的组合,第一反应就该去查 fs 是不是压得太低了。

5. 长序列卷积的分块实现与排查清单:重叠相加、重叠保留和五个翻车点

作业的第二部分是长序列线性卷积:一个序列很长、一个很短,直接conv在数据量大时算不动,要用 FFT 分块。两种经典分块思路对应两个函数,实现起来都不到二十行,但边界处理错了结果会整体偏移,而且前几十个点看着还挺对。

5.1 两种分块思路的差别

重叠相加法:把长序列切成互不重叠的块,每块和短序列做线性卷积,相邻块的结果有 M-1 个点重叠,把重叠部分加起来。每块的有效输出长度是 L,卷积结果长度是 L+M-1。

重叠保留法:每块取 L 个新样本,前面再带上 M-1 个已处理过的旧样本,凑成 L+M-1 点做循环卷积。循环卷积会让前 M-1 个点被尾部数据污染,所以这 M-1 个点直接丢弃,只保留后面 L 个点,块与块之间直接首尾拼接,不做加法。

两种方法计算量几乎一样,差别在数据管理和内存:重叠相加要维护一个带重叠区的输出缓冲,重叠保留只需顺序追加。实时流式处理一般选重叠保留,因为它每来 L 个新样本就能立刻输出 L 个点,不需要回头改已经写出去的结果。

5.2 重叠相加法实现

function y = ovl_add(x, h, Lfft) %OVL_ADD 重叠相加法计算线性卷积 x = x(:).'; h = h(:).'; M = length(h); if nargin < 3 || isempty(Lfft) Lfft = 2^nextpow2(4*M); % FFT 长度取 2 的幂,速度快 end L = Lfft - M + 1; % 每块有效数据长度 H = fft(h, Lfft); nx = length(x); nb = ceil(nx / L); y = zeros(1, nb*L + M - 1); % 预留尾部溢出空间 for m = 1:nb idx = (m-1)*L + 1 : min(m*L, nx); xm = x(idx); xm = [xm zeros(1, L - length(xm))]; % 末尾块补零到 L Ym = ifft(fft(xm, Lfft) .* H); seg = (m-1)*L + 1 : (m-1)*L + Lfft; y(seg) = y(seg) + real(Ym); % 重叠区累加 end y = y(1 : nx + M - 1); end

关键约束是Lfft >= L + M - 1,只要满足这一条,fft(xm, Lfft) .* H的点乘再做逆变换,等价于线性卷积而不是循环卷积,不会出现尾部绕回头部的情况。默认取4*M再向上取 2 的幂,是让 FFT 效率和数据块大小的折中;块太小则 FFT 调用次数多,块太大则缓存不友好。最后一行截掉预留的尾部,输出长度严格等于nx + M - 1。

5.3 重叠保留法实现

function y = ovl_save(x, h, Lfft) %OVL_SAVE 重叠保留法计算线性卷积 x = x(:).'; h = h(:).'; M = length(h); if nargin < 3 || isempty(Lfft) Lfft = 2^nextpow2(4*M); end L = Lfft - M + 1; % 每块输出的有效长度 nx = length(x); xp = [zeros(1, M-1) x zeros(1, L)]; % 头部补 M-1 个零,尾部留余量 nb = ceil(nx / L); H = fft(h, Lfft); y = zeros(1, nb*L); for m = 1:nb seg = (m-1)*L + 1 : (m-1)*L + Lfft; % M-1 点历史 + L 点新数据 Ym = ifft(fft(xp(seg), Lfft) .* H); y((m-1)*L+1 : m*L) = real(Ym(M : Lfft)); % 丢弃前 M-1 点 end y = y(1 : nx + M - 1); end

xp头部补的那 M-1 个零不是凑数,是为了让第一块也有「历史数据」,否则第一块的输出会整体前移。取Ym(M : Lfft)是丢弃被循环卷积污染的 M-1 个点,保留后面干净的 L 个点。这两处在写的时候都很容易漏,漏了不会报错,只是结果整体偏 M-1 个位置或者开头几个数不对。

5.4 正确性与计时:与 conv 逐点对齐

验证必须用已知长度的短序列,逐点比对,不能只看图的形状:

x = [1 2 3 4 5 1 3 4 3 4 5 4 3 4 6 7 3 2 6 7 1]; h = [1 2 3]; y0 = conv(x, h); y1 = ovl_add(x, h, 8); y2 = ovl_save(x, h, 8); fprintf('参考长度 %d,相加法 %d,保留法 %d\n', ... length(y0), length(y1), length(y2)); fprintf('相加法最大误差 %.3e\n', max(abs(y1 - y0))); fprintf('保留法最大误差 %.3e\n', max(abs(y2 - y0)));

Lfft取 8、M取 3,得到L = 6,长序列 21 点被切成 4 块。三个输出长度都应该是 23。误差在 1e-15 量级说明浮点舍入正常;出现 1e-1 量级说明边界处理错了;长度对不上说明尾部截断的公式写错了。

计时用tic/toc包住:

nx = 200000; nh = 256; rng(0); x = randn(1, nx); h = randn(1, nh); tic; y0 = conv(x, h); t_conv = toc; tic; y1 = ovl_add(x, h, 2^nextpow2(8*nh)); t_add = toc; tic; y2 = ovl_save(x, h, 2^nextpow2(8*nh)); t_save = toc; fprintf('conv %.4f s | 重叠相加 %.4f s | 重叠保留 %.4f s\n', t_conv, t_add, t_save);

直接卷积的复杂度是 O(nx·nh),分块 FFT 大约是 O(nx·log Lfft) 加上每次 FFT 的固定开销。nh小到几十的时候,直接conv往往还更快,因为 FFT 的调用开销压不住;nh上到几百、上千,分块法才明显胜出。这个交叉点必须自己测,不能凭感觉。

5.5 排查清单:五个最容易翻车的地方

现象一:所有谱线统一偏了 2 倍或 1/2 倍频率。原因通常是横轴写成了k/N(或n/N),而正确的归一化数字频率是2k/N。解决:把横轴改成2*k/N单位标为 ω/π,或者直接用k*fs/N标成赫兹,两种写法只能选一种,别混。

现象二:加窗后图变成一大片彩色,或者报矩阵维度错误。原因是triang/hanning/hamming返回列向量,x(1×M) .* w(M×1)触发隐式扩展成 M×M 矩阵。解决:窗向量统一转置成行向量,或者在函数入口处对所有输入做(:).'。

现象三:补零越多,幅度谱整体越矮。原因是归一化除以了补零后的点数而不是真实长度。解决:把真实长度N单独存一个变量,归一化、分辨率计算、横轴标定都用它;补零后的长度另起变量名M或Lfft。

现象四:重叠保留法的结果整体前移了 M-1 个点。原因是取输出时写成了Ym(1:L),忘了丢弃前 M-1 个被污染的点。解决:改成Ym(M : Lfft),并在验证时用conv逐点对齐,偏移一个点都能立刻发现。

现象五:补零后频谱出现对称的镜像峰。原因是把 0 到 N-1 的全段都画了出来,后一半是负频率的镜像,看起来像凭空多出几根谱线。解决:只取前floor(N/2)+1个点画单边谱,或者用fftshift把零频挪到中间再看双边谱。

6. 收尾前先跑三组验收:分辨率实测、泄漏量化、计时交叉点

代码能出图不算完,还得有办法证明它是对的。我一般会跑三组小实验做验收,每组都能给出一个数字,比看图靠谱。

6.1 分辨率实测:让两个峰刚好分开

构造两个等幅正弦,频率间隔已知,固定 fs 扫 N,记录「刚好能看出两个峰」的那个 N,再和理论值 2F 对一下:

fs = 100; f1 = 10; for dF = [1 2 5 10] N = 256; n = 0:N-1; x = sin(2*pi*f1*n/fs) + sin(2*pi*(f1+dF)*n/fs); X = abs(fft(x .* hamming(N)')) * 2 / N; X = X(1:N/2+1); fprintf('间隔 %2d Hz,理论分辨率 %.2f Hz,峰值间隔 %.2f Hz\n', ... dF, fs/N, mean(diff(findpeaks(X)))*fs/N); end

加汉宁窗之后主瓣宽度约 4F,间隔小于 4F 的两个峰基本分不开,实测结果会明显偏离理论分辨率,这正是「理论分辨率」和「实际可分辨能力」的差别。

6.2 泄漏量化:测旁瓣电平

对一个单频正弦做整周期截断和非整周期截断,比较最高旁瓣的相对电平,矩形窗大约 -13 dB、汉宁窗大约 -31 dB、海明窗大约 -43 dB。测出来的数字和这张表对不上,说明截断长度没控制好,或者归一化除错了。这一步能同时验证窗函数、截断长度和幅度标定三件事,值得固定成流程。

6.3 计时交叉点:什么时候分块 FFT 才真的赢

固定长序列长度,让短序列长度从 8 扫到 4096,每个长度各跑 20 次取平均,画出conv和分块法的耗时曲线。会看到两条线在某个nh附近交叉,交叉点左边的conv更快。这个交叉点跟机器、MATLAB 版本、内存都有关,抄别人的数字没意义,自己测一遍十分钟的事。测完心里就有数:短滤波器直接卷积,长滤波器才上分块。

最开始做这套实验的时候,我图省事,直接在原脚本上把N一路赋值覆盖,结果补零那一组的分辨率怎么算都和前面的对不上,折腾了一个晚上才发现是两个变量名撞了。从那以后我每次写频谱脚本,都强制把「真实长度」和「计算长度」分成两个变量,命名上必须能一眼区分;窗函数一律先转置成行向量再相乘。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询