
简介本资源为《现代数字信号复习题》配套习题文档面向正在学习数字信号处理课程的高校学生与考研复习者用于梳理核心概念并强化典型题型的解题思路。内容围绕数字信号处理基本概念、傅里叶变换、采样理论、数字滤波器与信号处理等模块展开涵盖采样频率与谱分辨率计算、A/D与D/A前后低通滤波器作用、系统因果性与稳定性判定、FIR与IIR滤波器对比及设计方案、功率谱估计与自适应滤波算法等常见考点并配有详细解答过程。资源包为1个doc文档大小约1.82MB结构紧凑便于打印或电子阅读。目前已有182人学习下载适合需要系统复习、对照例题查漏补缺的读者参考使用。1. 现代数字信号复习题为什么“刷题”救不了你但“重算一遍”可以如果你正在搜“现代数字信号复习题”大概率不是想找一份 PDF 题库而是发现自己把 DFT 的公式背得滚瓜烂熟一遇到“采样率 48 kHz、FFT 点数 1024、求频率分辨率”这种题还是卡壳。我带过几届做信号处理方向的实习生血泪经验是这门课挂的人往往不是没刷题而是刷题时跳过了“手算一遍中间量”这一步。现代数字信号处理的核心考点其实就四块离散时间系统与卷积、z 变换与频响、DFT/FFT 与频谱分析、FIR/IIR 滤波器设计。复习题的价值不在答案而在于逼你把每一问的中间结果算出来再用代码验证。这篇笔记面向正在备考或需要快速捡回 DSP 的工程师我会把典型复习题的解题路径拆成可复现的 Python 步骤告诉你哪些参数必须手算、哪些坑一踩就错以及怎么用几行代码给自己出题、对答案。2. 从复习题到可运行验证先把四类母题拆开2.1 复习题里反复出现的四类母题翻遍常见的现代数字信号处理习题集题目花样再多底层就四类母题在反复变形。第一类是离散时间系统分析给差分方程或单位脉冲响应求卷积、判断因果稳定性、画零极点图。第二类是变换域计算z 变换、DTFT、DFT 之间的换算重点考频域采样和泄漏。第三类是频谱分析给采样率和点数求分辨率、主瓣宽度、加窗后的影响。第四类是滤波器设计用窗函数法或双线性变换法设计 FIR/IIR验证通带阻带指标。复习时最忌讳按章节顺序从头刷到尾因为考试和实际工程都是混合出题。我一般建议按母题归类每类先手算两道再用代码把同一道题重算一遍。手算负责暴露你对公式边界的理解代码负责告诉你数值上到底差多少。两者对不上那道题才是你真正需要反复看的题。2.2 用 Python 搭一个“复习题验证器”与其到处找答案不如自己搭一个最小验证环境。下面这段代码把四类母题里最常用的计算封装成函数你做完一道题就调一次看手算结果和数值结果是否一致。import numpy as np from scipy import signal def conv_check(x, h): 手算卷积后用它验证直接卷积 vs FFT 卷积 y_direct np.convolve(x, h, modefull) n len(x) len(h) - 1 nfft 1 (n - 1).bit_length() # 补到 2 的幂避免循环卷积混叠 y_fft np.fft.ifft(np.fft.fft(x, nfft) * np.fft.fft(h, nfft)) y_fft np.real(y_fft[:n]) return y_direct, y_fft def freq_resolution(fs, N): 频率分辨率复习题最爱考的第一问 return fs / N def dft_bin(fs, N, k): 第 k 根谱线对应的模拟频率 return k * fs / N # 示例x [1,2,3], h [1,1] x np.array([1, 2, 3]) h np.array([1, 1]) yd, yf conv_check(x, h) print(直接卷积:, yd) print(FFT 卷积 :, np.round(yf, 10)) print(分辨率(48k,1024):, freq_resolution(48000, 1024), Hz) print(第 100 根谱线:, dft_bin(48000, 1024, 100), Hz)这段代码的关键在nfft的取法。很多人直接用len(x)len(h)-1做 FFT 点数结果发现 FFT 卷积和直接卷积对不上原因是点数不是 2 的幂时某些实现会补零到邻近的 2 的幂补零位置不对就会引入循环卷积混叠。(n-1).bit_length()是取不小于 n 的最小 2 的幂的标准写法记住它。freq_resolution和dft_bin两个函数看着简单但复习题里至少三成计算错误出在把分辨率当成fs/N之外的东西或者把第 k 根谱线频率写成k*fs/(N-1)。参数说明fs是采样率单位 HzN是 FFT 点数不含补零k从 0 开始计数。2.3 手算和代码对不上时先查这三个地方对不上是好事说明你找到了知识漏洞。按我的排查顺序先查卷积长度线性卷积长度是LM-1循环卷积长度等于 FFT 点数两者相等才没有混叠。再查频率轴DFT 的频率索引是k0...N-1对应0到(N-1)/N * fs负频率在kN/2部分。最后查窗函数复习题里如果出现“加矩形窗”“加汉宁窗”主瓣宽度和旁瓣衰减会变手算时容易漏掉窗因子的归一化系数。提示手算卷积时把x和h都写成序列形式逐项相乘再相加不要跳步。跳步是复习阶段最大的坑因为考试时没有代码帮你兜底。3. DFT 与频谱分析复习题参数怎么设、结果怎么读3.1 频率分辨率、主瓣宽度、栅栏效应三者的关系复习题里最经典的组合问法是给采样率fs、信号频率f0、FFT 点数N问能不能分辨两个靠近的频率分量。很多人只记“分辨率 fs/N”但题目往往还要求你考虑窗函数。矩形窗的主瓣宽度约为2*fs/N汉宁窗约为4*fs/N。也就是说加汉宁窗后分辨率名义值没变但实际可分辨的最小间隔变大了。栅栏效应是另一个高频考点DFT 只在离散频点上看频谱如果信号频率落在两根谱线之间幅度会泄漏到相邻谱线。复习题常让你算泄漏后的幅度误差或者问补零能不能提高分辨率。标准答案是补零只能让谱线更密不能提高物理分辨率因为分辨率由观测时间T N/fs决定补零不增加观测时间。3.2 用代码复现一道典型频谱分析题假设复习题给出fs 8000 Hz信号为x(t) cos(2π*1000t) 0.5*cos(2π*1250t)用N 64点矩形窗做 FFT问能否分辨两个分量。手算分辨率8000/64 125 Hz两分量间隔250 Hz大于分辨率理论上可分辨。但矩形窗主瓣宽度约2*125 250 Hz刚好等于间隔实际会糊在一起。下面用代码验证。import numpy as np import matplotlib.pyplot as plt fs 8000 N 64 n np.arange(N) x np.cos(2*np.pi*1000*n/fs) 0.5*np.cos(2*np.pi*1250*n/fs) # 不加窗 X np.fft.fft(x, N) f np.fft.fftfreq(N, 1/fs) # 加汉宁窗 w np.hanning(N) Xw np.fft.fft(x*w, N) plt.figure(figsize(10,4)) plt.subplot(1,2,1) plt.stem(f[:N//2], np.abs(X[:N//2]), basefmt ) plt.title(矩形窗 N64) plt.xlabel(Hz) plt.subplot(1,2,2) plt.stem(f[:N//2], np.abs(Xw[:N//2]), basefmt ) plt.title(汉宁窗 N64) plt.xlabel(Hz) plt.tight_layout() plt.show() # 打印峰值附近谱线 idx np.argsort(np.abs(X[:N//2]))[-4:] print(矩形窗峰值谱线(Hz):, np.sort(f[idx]))运行后你会看到矩形窗下 1000 Hz 和 1250 Hz 附近谱线连成一片汉宁窗下主瓣更宽但旁瓣更低。这道题在复习题里的标准问法是“能否分辨”答案要分两层按分辨率公式能按主瓣宽度不能实际工程中通常取N加倍到 128 再判断。参数说明np.fft.fftfreq(N, 1/fs)生成频率轴前半段是正频率np.hanning(N)是汉宁窗注意它两端为零会损失一点信号能量所以幅度要乘归一化系数2/sum(w)才能还原真实幅度复习题里如果要求幅度精确值这一步不能漏。3.3 补零、截断、加窗的复习题陷阱补零的陷阱在于补零后 FFT 点数变大fs/N变小很多人误以为分辨率提高了。正确理解是补零相当于在频域插值让谱线更密但主瓣宽度由原观测长度决定不会变窄。截断的陷阱在于截断长度不是整数个周期时频谱泄漏严重复习题常让你算泄漏到相邻谱线的能量占比。加窗的陷阱在于不同窗的幅度恢复系数不同矩形窗是1/N汉宁窗是2/sum(w)布莱克曼窗又不一样题目如果要求“求真实幅度”系数用错直接扣分。注意复习题里出现“补零到 1024 点”时先问自己原观测点数是多少。如果原观测点数是 64补零到 1024 只是让频率轴更密分辨率仍然是fs/64。4. FIR 与 IIR 滤波器设计复习题指标怎么转、系数怎么算4.1 窗函数法设计 FIR 的完整计算链FIR 滤波器设计是复习题里计算量最大的一类但步骤非常固定。给定通带截止频率fp、阻带截止频率fs、阻带衰减As先选窗函数矩形窗As≈21 dB汉宁窗44 dB汉明窗53 dB布莱克曼窗74 dB。再算过渡带宽度Δf fs - fp窗函数主瓣宽度决定所需阶数N ≈ 窗系数 * fs / Δf。最后用理想低通冲激响应hd[n] sin(ωc(n-M))/ (π(n-M))加窗截断。复习题常考的细节是N取奇数还是偶数。如果要求线性相位且类型 IN取奇数类型 II 取偶数。窗函数法通常取N为奇数中心点M (N-1)/2是整数方便对称。另一个细节是截止频率ωc取通带和阻带的平均值即(fpfs)/2不是单独取fp或fs。4.2 用代码把设计指标转成滤波器系数下面这段代码把上述步骤串起来你可以拿它验证复习题里手算的N和系数。import numpy as np def fir_lowpass(fp, fs, fsample, As): 窗函数法设计低通 FIR fp, fs: 通带、阻带截止频率(Hz) fsample: 采样率(Hz) As: 阻带最小衰减(dB) # 根据 As 选窗 if As 21: win_name, beta rect, 0 elif As 44: win_name, beta hann, 0 elif As 53: win_name, beta hamming, 0 else: win_name, beta blackman, 0 df fs - fp # 各窗过渡带系数经验值 coef {rect: 0.9, hann: 3.1, hamming: 3.3, blackman: 5.5} N int(np.ceil(coef[win_name] * fsample / df)) if N % 2 0: N 1 # 取奇数保证类型 I 线性相位 M (N - 1) // 2 fc (fp fs) / 2 wc 2 * np.pi * fc / fsample n np.arange(N) hd np.sin(wc * (n - M)) / (np.pi * (n - M)) hd[M] wc / np.pi # 处理 0/0 if win_name rect: w np.ones(N) elif win_name hann: w np.hanning(N) elif win_name hamming: w np.hamming(N) else: w np.blackman(N) h hd * w return h, N, win_name h, N, win fir_lowpass(fp1000, fs1500, fsample8000, As50) print(窗类型:, win, 阶数 N:, N) print(前 5 个系数:, np.round(h[:5], 6)) print(系数和(应接近 1):, np.sum(h))参数说明fp和fs单位 Hz必须满足fs fpAs是阻带衰减决定窗类型coef里的系数是各窗过渡带宽度与fsample/N的经验比例不同教材略有差异复习题如果给了具体公式以题目为准。hd[M] wc/np.pi是处理中心点的极限值漏掉这行会出现nan。系数和接近 1 说明直流增益正确如果明显偏离 1检查wc是否算错。4.3 IIR 双线性变换法复习题的三个易错点IIR 设计复习题通常给模拟原型H(s)要求用双线性变换法求H(z)。三个易错点第一预畸变公式Ω 2*fs*tan(ω/2)里的fs是采样率不是1很多人直接代tan(ω/2)导致频率映射错误。第二双线性变换的代入式是s 2*fs*(1-z^-1)/(1z^-1)分子分母的2*fs不能漏。第三变换后要检查稳定性模拟左半平面映射到单位圆内如果H(z)有极点在单位圆外说明预畸变或代入过程出错。复习题里常把这三步拆成三小问每问都有分。我的建议是手算时把s的代入式完整写出来不要跳步然后用scipy.signal.bilinear验证系数。from scipy import signal import numpy as np # 模拟原型 H(s) 1 / (s 1) b_analog [1] a_analog [1, 1] fs 1000 # 采样率 b_digital, a_digital signal.bilinear(b_analog, a_analog, fs) print(数字滤波器分子系数:, np.round(b_digital, 6)) print(数字滤波器分母系数:, np.round(a_digital, 6)) # 检查极点是否在单位圆内 z, p, k signal.tf2zpk(b_digital, a_digital) print(极点模值:, np.abs(p))运行后极点模值应小于 1。如果手算结果和signal.bilinear对不上先查预畸变频率是否用对再查s代入式是否漏了2*fs。5. 复习题避坑与排查五条血泪记录5.1 现象卷积结果长度对但数值整体偏移原因手算时把序列下标从 1 开始代码里从 0 开始导致每一项错位。解决统一用 0 起始下标手算时在草稿纸上标清楚x[0]对应哪个时刻。5.2 现象FFT 幅度和理论值差一倍原因单边谱和双边谱混淆。np.fft.fft输出的是双边谱正频率部分幅度要乘 2 才是单边谱幅度直流和奈奎斯特分量不乘。解决复习题里如果问“求幅度谱”先看题目要单边还是双边单边就乘 2 并只取前N/21点。5.3 现象滤波器系数对称但频响不满足指标原因阶数N取成了偶数导致类型 II 线性相位在奈奎斯特频率处强制为零高频指标不达标。解决窗函数法一律取奇数阶N 2M1中心点M为整数。5.4 现象双线性变换后低频段吻合高频段偏差大原因双线性变换的频率非线性映射高频被压缩。复习题如果要求“在某个频率点精确匹配”必须先用预畸变把数字频率转成模拟频率再设计。解决记住预畸变公式Ω 2*fs*tan(ω/2)ω是数字角频率。5.5 现象加窗后主瓣变宽题目问“分辨率是否变化”原因把“分辨率”和“可分辨能力”混为一谈。分辨率名义值fs/N不变但主瓣变宽导致实际可分辨间隔变大。解决答题时分两句写先写名义分辨率再写窗函数影响不要只写一个数。注意复习题里凡是出现“能否分辨”“是否满足指标”这类判断都要把计算过程和结论分开写结论错但过程对通常还能拿步骤分。6. 用代码给自己出题把复习题变成可验证的练习集复习到后期最有效的方法不是继续找题而是自己出题。我的习惯是写一个小脚本随机生成信号参数和滤波器指标先手算再让脚本算标准答案对不上就回去查。下面这个脚本每次运行生成一道随机频谱分析题和一道 FIR 设计题你可以把它当成每日一练。import numpy as np def gen_spectrum_question(): fs np.random.choice([4000, 8000, 16000, 48000]) N np.random.choice([32, 64, 128, 256]) f1 np.random.randint(100, fs//4) f2 f1 np.random.randint(50, fs//8) return fs, N, f1, f2 def gen_fir_question(): fsample np.random.choice([8000, 16000, 44100]) fp np.random.randint(500, fsample//4) df np.random.randint(200, 800) fs fp df As np.random.choice([30, 45, 60, 80]) return fp, fs, fsample, As fs, N, f1, f2 gen_spectrum_question() print(f频谱题: fs{fs}, N{N}, f1{f1}, f2{f2}) print(f分辨率{fs/N:.1f} Hz, 间隔{f2-f1} Hz, 矩形窗主瓣宽≈{2*fs/N:.1f} Hz) fp, fs_, fsample, As gen_fir_question() print(fFIR题: fp{fp}, fs{fs_}, fsample{fsample}, As{As} dB) print(f过渡带{fs_-fp} Hz, 建议阶数≈{int(np.ceil(3.3*fsample/(fs_-fp)))} (汉明窗))每次运行后先拿纸笔算一遍再用第 3、4 章的验证函数对答案。坚持两周你会发现复习题里那些“看起来会、一做就错”的题错误率明显下降。我自己的教训是复习阶段最没用的动作是反复看例题答案最有用的动作是把同一道题的手算过程写三遍再用代码跑三遍直到两者完全一致。这个习惯后来做实际信号处理项目时也一直在用因为工程里没有人给你答案你只能自己给自己出题、自己验证。希望帮到你。本文还有配套的精品资源点击获取