简介这份《信号与系统课后答案》PDF面向电子工程、通信工程等专业学习“信号与系统分析”课程的学生尤其适合南京邮电大学相关课程的学习者用于课后习题核对、周期性与抽样等概念梳理。压缩包内仅含1个PDF文件大小约1.12MB目录围绕第一章信号与系统的基本概念展开涵盖连续周期信号判断与基本周期求解、离散周期序列识别及最小公倍数周期计算、两个周期信号相加仍为周期信号的条件证明、连续信号均匀抽样后数字角频率与序列周期的分析以及能量信号、功率信号与非能非功信号的判定。文档保留了较完整的解题过程、定义式推导和波形说明便于读者对照课堂进度查漏补缺理解周期性、抽样与信号分类之间的关联。目前已有3934人学习适合作为阶段性复习和习题自检的参考材料。1. 课后答案 PDF 只给你结果验证链才给你过程信号与系统这门课的课后答案几乎每个学过的人手里都有一份。真到复习或者考研二轮刷题的时候翻两次就发现它不好用一道 20 分的卷积题答案常常只写「y(t) e^{-t} - e^{-2t}t ≥ 0」中间两页推导被压缩成一行你错在哪里完全看不出来。更麻烦的是符号约定有的写 jω有的写 iω单边拉普拉斯和双边混着用离散题的 n 起点从 0 还是从 1 开始也不统一直接照抄答案反而会把错误的过程固化下来。我后来换了个思路把课后答案 PDF 当成一套测试用例集而不是教材。每道题的最终结果是一个 assert我要做的是自己求出解析解、用数值方法复现一遍、再用频域或时域的另一条路径交叉验证三条链都过了才算这道题做对。这个做法对本科生复习、考研二轮、以及工作后要补离散时间系统前置知识的人都适用代价是一道题多花五到十分钟收益是你能定位到自己到底错在哪一步而不是对着答案发呆。2. 一道卷积题拆成三条独立的验证链2.1 先把解析解推到能写进代码的形式拿最经典的连续卷积举例x(t) e^{-t}u(t)h(t) e^{-2t}u(t)求 y(t) x(t) * h(t)。手算得到 y(t) (e^{-t} - e^{-2t})u(t)。很多人算到这一步就停了把结果和答案对一下了事。但「能写进代码的形式」要求更高你得明确 t 的定义域、明确 u(t) 在 t0 处的取值约定、明确结果在 t→∞ 时的衰减速度。这里有个容易被忽略的点解析解的有效区间。卷积结果在 t 0 时为 0是因为两个信号都从 0 开始如果换成 x(t) u(t) - u(t-2)y(t) 的表达式就要分成 0 ≤ t 2 和 t ≥ 2 两段答案 PDF 里经常只写第二段照着抄必翻车。我一般会把分段条件先在纸上写清楚再动手敲代码否则数值验证的时候会被边界那一点误差折磨很久。还有一个习惯先把解在几个特殊点上手算一遍比如 t0、tln2这里是峰值、t1、t5。t0 时 y0tln2 时 y0.25t1 时 y≈0.2326。这几个点后面拿来核对数值结果比看曲线形状可靠得多。2.2 数值卷积只是矩形积分的近似步长怎么定连续卷积的定义是积分代码里能做的只有离散求和。最朴素的近似是把积分拆成矩形import numpy as np dt 1e-4 # 采样步长取最快时间常数的 1/100 t np.arange(0, 6, dt) # 6 个时间单位足够看到衰减尾巴 x np.exp(-t) # x(t) e^{-t} u(t)t 0 h np.exp(-2 * t) # h(t) e^{-2t} u(t) y_num np.convolve(x, h) * dt # 离散卷积补偿 dt 才能逼近积分 t_num np.arange(len(y_num)) * dt # 结果长度 len(x) len(h) - 1 y_ref np.exp(-t_num) - np.exp(-2 * t_num) # 解析解 mask t_num 6 err np.max(np.abs(y_num[mask] - y_ref[mask])) print(max abs error:, err)这段代码跑出来的绝对误差在 1e-4 量级正好和 dt 同阶说明离散近似本身收敛正常如果误差跑到 1e-2 甚至更大那一定不是精度问题而是某个参数写错了。关键参数只有两个。dt 决定积分近似的精度经验值是取系统最快时间常数的 1/50 到 1/100这里最快时间常数是 e^{-2t} 对应的 0.5所以 dt 1e-4 相当于 1/5000够用且不慢。t 的终点取最长衰减的 5 到 7 倍e^{-t} 在 t6 时已经衰到 0.0025再往后算只是浪费内存。还有一个坑np.convolve 默认是「full」模式结果长度是 2N-1很多人直接拿它和长度 N 的参考信号相减numpy 会广播报错或者悄悄错位。正确做法是用 t_num 重新生成参考信号保证两边长度一致再截取有效区间比较。2.3 频域相乘做第三条链量纲与对称性检查时域验证过了还不够因为时域近似和解析解可能同时错在同一个地方比如都把 u(t) 的起点弄错了。第三条链是走频域卷积在频域是相乘如果 Y(jω) X(jω)H(jω) 也对得上那基本可以放心。用 DFT 近似连续傅里叶变换时有一个必须补偿的因子X[k] ≈ dt · Σ x[n]e^{-j2πkn/N}频率轴是 f_k k/(N·dt)ω 2πf。import numpy as np a 1.0 dt 1e-4 N 2 ** 18 # 总时长 N*dt ≈ 26.2 s保证截断误差可忽略 t np.arange(N) * dt x np.exp(-a * t) X np.fft.fft(x) * dt # 乘 dt 才是积分近似 f np.fft.fftfreq(N, ddt) w 2 * np.pi * f X_ref 1 / (a 1j * w) # 解析的傅里叶变换 sel (f 0) (f 5.0) # 只信低频段高频段受离散化影响大 rel np.abs(X[sel] - X_ref[sel]) / np.abs(X_ref[sel]) print(max rel err:, rel.max())三个参数控制着这条链的质量。N·dt 决定截断误差要让 e^{-a·N·dt} 小到可忽略26 秒时 e^{-26} ≈ 5e-12随便用dt 决定矩形积分的相位误差量级是 O(ω·dt)所以只在 f 5 Hzω 31.4的范围内比较相对误差能压到 1e-3 以内频率比较窗口的选择本质上是在「信噪比」和「适用频段」之间取折中超过 1/(2dt) 的奈奎斯特频率之后DFT 结果和连续变换没有可比性。我通常会用一张小表把三条链的结果记下来解析解特殊点值、时域数值最大误差、频域相对误差。三个数都在预期量级这道题才算过任何一个超出一个数量级回去查参数。3. 把验证脚手架写成脚本三个校验器覆盖八成题型3.1 时间轴与采样率一个函数管住所有题做完十道题之后你会发现大部分时间花在重复写时间轴、重复定 dt 上。把这几行抽成函数后面每道题只写解析表达式和参考解。import numpy as np def time_axis(t_end, fastest_tau, points_per_tau100): 按最快时间常数自动定步长返回 (t, dt) dt fastest_tau / points_per_tau n int(np.ceil(t_end / dt)) return np.arange(n) * dt, dt def ct_conv(x, h, dt, t0_x0.0, t0_h0.0): 连续卷积的离散近似起点按时移对齐返回 (t, y) y np.convolve(x, h) * dt t (t0_x t0_h) np.arange(len(y)) * dt return t, ytime_axis 的第二个参数 fastest_tau 是这道题里衰减最快的那个时间常数points_per_tau 取 100 是保守值遇到振荡信号比如 e^{-t}sin(10t)要按振荡周期而不是衰减常数来定改用每周期 20 到 50 点。ct_conv 里 t0_x 和 t0_h 这两个时移参数是血泪经验换来的。信号带时移比如 u(t-2)时卷积结果的起点是 t0_x t0_h而不是 0。如果忘了这一步时间轴整体偏移和解析解一比就到处对不上而你大概率会先去怀疑步长不够白白调半天。3.2 三个校验器卷积、变换对、差分方程除了卷积课后题主要就三类拉普拉斯/Z 变换对、系统响应冲激响应、阶跃响应、差分方程递推。每类写一个校验器用同一个报错格式跑完一批题直接看哪几道红了。变换对的校验用部分分式展开scipy 的 residue 可以直接把有理函数拆成留数和极点import numpy as np from scipy.signal import residue # H(s) (s 3) / (s^2 3s 2) 2/(s1) - 1/(s2) b [1, 3] a [1, 3, 2] r, p, k residue(b, a) for ri, pi in zip(r, p): print(f留数 {ri:.4f} 极点 {pi:.4f}) print(直接项 k , k)输出是留数 [2, -1]、极点 [-1, -2]对应 h(t) (2e^{-t} - e^{-2t})u(t)和手算一致。这里的参数顺序要注意residue 的 b 是分子系数按 s 的降幂a 是分母系数两边都要补齐缺项比如 s^2 2 要写成 [1, 0, 2]少写一个 0 结果全错。差分方程的校验换个思路给系统喂一个正弦等稳态之后测幅度和频率响应 |H(e^{jΩ})| 比。import numpy as np from scipy.signal import lfilter a 0.9 b_coef [1.0] a_coef [1.0, -a] # y[n] x[n] 0.9 y[n-1] w0 0.4 * np.pi n np.arange(4000) y lfilter(b_coef, a_coef, np.sin(w0 * n)) tail y[3000:] # 跳过暂态 amp_meas np.sqrt(2 * np.mean(tail ** 2)) # 正弦 RMS 反推幅度 amp_ref 1 / np.abs(1 - a * np.exp(-1j * w0)) print(measured:, amp_meas, theory:, amp_ref)用 RMS 反推幅度而不是取最大值是因为采样点未必正好落在峰值上w0 0.4π 时每周期只有 5 个点取最大值会低估接近 20%。跳过前 3000 点是因为一阶系统的暂态衰减到 1e-3 需要大约 65 个时间常数3000 点已经绰绰有余。这个校验器的价值在于它验证的是时域实现和频域理论的一致性比单纯比对公式更有工程味。3.3 残差报告怎么写才有用跑完一批题输出不能只有一句「通过」。我一般让每个校验器返回三个字段题号、最大绝对误差、最大相对误差最后拼成一张表。绝对误差看的是量级对不对相对误差看的是形状对不对两者要一起看。举个例子卷积题如果绝对误差 1e-4、相对误差 1e-3说明参数都对如果绝对误差很小但相对误差 0.5大概率是解析解在某个区间接近零分母把误差放大了这时候要检查是不是区间截取错了如果两个都大先看时间轴起点再看 dt最后才怀疑解析解。这张表攒到二十道题以后会非常有用你能看出自己哪一类题的错误率高。我当时发现自己所有带时移的题都偏回头一查全是 ct_conv 里没传 t0这就是把踩过的坑变成了检查项。4. 连续题和离散题混着做四个必须先对齐的换算4.1 拉普拉斯与 Z 变换收敛域不是装饰课后答案最常见的偷懒是只给表达式不给收敛域。H(s) 1/(s1) 到底是因果系统还是反因果系统光看表达式分不出来必须看 ROC。这一点在做逆变换和判断稳定性时是决定性的同一个表达式ROC 在 Re(s) -1 对应右边信号 e^{-t}u(t)ROC 在 Re(s) -1 对应左边信号 -e^{-t}u(-t)两者完全不同的时域波形。离散侧同理。H(z) 1/(1 - 0.9z^{-1})若 ROC 是 |z| 0.9对应 0.9^n u[n]稳定若 ROC 是 |z| 0.9对应 -0.9^n u[-n-1]不稳定。数值验证的时候如果你的信号生成方式和 ROC 不匹配跑出来的结果和理论永远差一个符号而且这个符号很难从曲线上看出来。我在脚手架里加了一个约定每道题先写一行注释记 ROC代码里生成信号时按 ROC 选 u[n] 还是 u[-n-1]这样后面出问题能第一时间排除这一项。变换定义式要点收敛域常见写错的地方连续傅里叶∫x(t)e^{-jωt}dt绝对可积ω 与 2πf 混用拉普拉斯∫x(t)e^{-st}dts σ jωRe(s) 极点实部最大值单边变换误用于双边信号DTFTΣx[n]e^{-jΩn}单位圆上收敛Ω 与 ω 混用差一个 TsZ 变换Σx[n]z^{-n}z re^{jΩ}z4.2 频率归一化ω、f、Ω 之间只差一个 2π 和一个 Ts连续域的角频率 ωrad/s、普通频率 fHz、离散域的归一化角频率 Ωrad三者之间的换算是错得最多的地方而且错了之后现象很迷惑波形看起来对但周期差了一截。关系是 ω 2πfΩ ωTs 2πf/fs。代码里 np.fft.fftfreq 返回的是 f单位 Hz要转成 ω 得乘 2π而 scipy.signal.freqz 返回的是归一化频率0 到 π要转成 ω 得除以 Ts 再乘 2π……等一下freqz 返回的 w 本身就是 Ωrad/sample不需要再除 Ts它的物理含义是数字角频率和连续域的 ω 差了采样率这一层。我踩过的最典型的一次用 freqz 算出一阶系统的截止频率把返回值当成 rad/s 直接和模拟滤波器的指标对比结论是「数字滤波器带宽只有设计值的一半」排查了半天才发现是漏了乘以采样率。从那以后我在脚手架里强制变量命名带单位后缀w_rad_s、w_rad_sample、f_hz混用会直接报错。4.3 部分分式展开的数值稳定性与留数符号residue 在极点接近时会出问题。教材题目一般都设计成互异极点但如果你自己扩展到高阶系统重极点会让 residue 返回一堆相邻极点和巨大留数虽然数学上仍然正确数值上极点轻微分裂但生成的时域表达式会很长看起来完全不像课本答案。遇到重极点正确做法是手工用 (s-p)^k 的形式推或者改用符号计算下一章会说。数值方法在这里只能做验证不能替代推导。留数的符号也是高频错误点。residue 返回的 r 是 H(s) Σ r_i/(s - p_i) k(s)注意分母是 (s - p_i)当 p_i -1 时就是 (s 1)这个负号变化很容易在抄进代码时丢掉。我的做法是先打印出来再和手算的留数逐个比对对不上就停不要往下跑。5. 避坑与排查五个把我按回桌前重算的细节5.1 卷积的起点与时移对齐现象带时移的题数值解和解析解在 t 轴上整体错开一段误差曲线在边界处冒出一个大尖峰中间段反而对得很准。原因np.convolve 只做下标卷积不知道信号在物理时间上从哪开始。x(t) u(t-2) 和 h(t) e^{-t}u(t) 卷出来结果的起点是 2但代码默认从 0 开始铺时间轴。解决给 ct_conv 传 t0_x 和 t0_h返回的 t 用两者之和做起点。养成习惯只要信号里有 u(t - a)就把 a 记下来传进去。另外参考信号生成时也要用同一个 t 数组别用 np.arange(len(y)) * dt 重新造一个。5.2 单边与双边变换混用现象逆拉普拉斯变换的结果符号和答案相反或者多出一个 u(-t)。原因答案用的是双边变换或者带 ROC 的逆变换代码里按因果信号处理了。sympy 的 inverse_laplace_transform 默认按因果解释scipy 的 residue 只给代数分解两者都不管 ROC。解决先在注释里写清信号是右边、左边还是双边再选对应的生成方式。验证时把 t 轴扩展到负半轴左边信号在 t0 有值右边信号在 t0 为 0一眼就能看出来。5.3 采样率不足导致的假对齐现象低通滤波器的频率响应用 DFT 验证低频段完全吻合高频段误差很大但你怎么调 N 都压不下去。原因dt 太大奈奎斯特频率低于你比较的最高频率高频段的 DFT 结果已经混叠了。解决比较窗口的上限不超过 0.4/dt留 20% 余量或者干脆把 dt 减半再看误差是否随 dt 线性下降。误差随 dt 一阶下降说明是矩形积分误差不下降说明是混叠或者截断这两个原因用这个办法能分开。5.4 序号从 0 还是从 1 开始现象离散题的结果整体移位一位比如 h[n] a^n u[n] 算出来 h[0] 对不上。原因有些资料写 u[n] 从 n1 开始有些从 n0 开始MATLAB 系的索引从 1 开始Python 从 0 开始。解决全篇统一用「n ≥ 0 时 x[n] 有值」的约定代码里 np.arange(N) 就是 n。遇到和答案差一位的情况先检查这个约定不要急着改解析解。5.5 分母补零与系数顺序现象residue 报错「First denominator polynomial must be nonzero」或者返回的极点完全不对。原因多项式系数没有按降幂补齐比如 s^2 2 写成了 [1, 2]被解析成 s 2。解决写一个小的构造辅助函数输入极点列表直接生成系数避免手写数组import numpy as np def denom_from_poles(poles): 由极点列表生成降幂排列的分母系数 return np.real(np.poly(poles)).tolist() print(denom_from_poles([-1, -2])) # [1.0, 3.0, 2.0] 即 s^2 3s 2这类小工具攒到十几个之后写题的速度会明显变快出错率也降下来了。每一类题先手算一个标准答案存成测试用例后面遇到同类题直接跑这个习惯比背答案有用得多。6. 用符号计算给每道题配一个自动判卷器数值验证有个天花板它只能告诉你「这条路径算出来的数对不对」不能告诉你「表达式能不能化简成课本那个形式」。这时候上符号计算把推导也交给机器。import sympy as sp s, t, tau sp.symbols(s t tau, positiveTrue) H (s 3) / (s ** 2 3 * s 2) h sp.inverse_laplace_transform(H, s, t) print(h(t) , sp.simplify(h)) # 2*exp(-t) - exp(-2t) # 直接做卷积积分验证 2.1 节的解析解 x sp.exp(-tau) y sp.integrate(x * sp.exp(-2 * (t - tau)), (tau, 0, t)) print(y(t) , sp.simplify(y)) # exp(-t) - exp(-2t)两段输出和手算完全一致而且符号计算不引入步长误差这是它比数值方法强的地方。参数上唯一的讲究是 symbols 的 positiveTrue不加的话 sympy 会给你一堆分段函数看起来吓人其实只是它在考虑 t0 的情况。我的自动判卷流程分三层符号层判表达式是否等价用 sp.simplify(a - b) 0数值层判特殊点是否吻合图形层人眼看一眼形状。三层里符号层最快数值层最可靠图形层只做兜底。三者组合八成课后题都能在几分钟内确认。顺手记一张对照表下次遇到同类题直接查题型首选校验手段精度预期主要风险连续卷积时域数值 频域相乘绝对误差 1e-4 量级时移起点没对齐逆拉普拉斯sympy 逆变换 特殊点表达式级精确ROC 没约定导致分段差分方程lfilter 稳态幅度相对误差 1e-3 量级暂态没跳干净频率响应DFT 低频段比较相对误差 1e-3 量级比较窗口超出奈奎斯特说个我自己的教训。刚开始做这套东西的时候我把精力全放在调误差上误差大就加采样点加到内存爆掉还是不对后来才发现是时间轴起点错了加多少点都没用。所以现在的顺序是先对齐物理量起点、单位、ROC再看数值精度最后才动参数。数值方法是个黑匣子你喂进去的物理约定错了它只会安静地给你一个看起来很漂亮的错误答案。这套流程做顺之后一份课后答案 PDF 的价值就不在「对答案」上了而在「给你一套标准输出」剩下的推导和验证都是你自己长出来的能力。希望帮到你。本文还有配套的精品资源点击获取