MATLAB连续时间信号卷积实现:Ts缩放与时轴重建的避坑指南
简介面向数字信号处理课程学习者的一份文档资料围绕连续时间信号卷积运算的MATLAB实现展开既涵盖卷积概念与物理意义的理论讲解也给出完整的实验目的、实验原理、参考代码与结果分析适合配合课程实验或课后复习使用。资源为单份doc格式文档整体压缩包大小186KB内容紧凑完整覆盖实验目的、参考程序、结果分析与心得并包含sconv函数自定义实现、示例运行命令与波形结果图便于快速查阅并直接运行实例。已有436人学习下载。文档详细展示了基于sconv函数结合conv完成连续信号卷积的过程并对比抽样时间p0.5与p0.01下的波形差异帮助理解数值近似原理同时提供实验要求与心得便于读者在课本课后习题中自行练习巩固对单位冲激响应和卷积物理含义的掌握。1. 连续时间信号卷积运算的 MATLAB 实现先绕开这两个坑信号与系统课上用笔算的连续卷积是一个积分式考试时思路清楚换成 MATLAB 反而容易出问题。原因不复杂MATLAB 工作区里没有真正意义上的连续时间信号任何波形存下来都是一串按固定采样间隔排列的数值点。所谓“连续时间信号卷积运算的 MATLAB 实现”实际是在用离散方法逼近连续积分。这个实验最常见的两个败笔一是只写一句conv(x, h)忘了在结果后面乘采样间隔Ts图形形状对了幅度整体缩小几百倍二是没有重建卷积结果的时间轴直接用两个输入的长度硬凑坐标曲线整体偏移和理论解怎么都对不上。把这两件事先想清楚剩下的事情就是按符号积分、数值积分、离散卷积三条路径互相验证。这篇内容直接针对课程实验二先用int做解析法打底再用conv做离散实现最后用一组单位冲激自检命令在提交报告前一次性找出幅度和时轴错误。新手可以顺着命令走已经做过实验的人可以重点看第 3 章的时轴公式和第 5 章的冲激自检。2. 连续卷积的符号积分用 int 求出闭式解的最小流程2.1 连续卷积实验到底在算什么先分清 t 和 τ连续时间卷积的定义是y(t) ∫_{-∞}^{∞} x(τ) h(t−τ) dτ。写代码前需要把三个变量分开t是输出信号的时间τ是积分变量t−τ描述的是h的翻转和平移。符号积分路线就是把被积函数里的heaviside、指数、矩形脉冲全部放进符号变量交给int处理最后得到y(t)的分段闭式表达式。这里有一个值得写进实验报告的理解int求出来的是解析解适合作为评价数值结果的标准conv求出的是数值解适合用来画图、验证性质和做面积校验。两边都做而不是只交一张 plot 出来的图。很多实验报告只贴了conv结果评委老师一问“理论值是什么”就答不上来这个环节扣分最亏。2.2 从定义到闭式解syms/int 的最小代码用一组最经典信号演示x(t) e^{-t}u(t)h(t) u(t) - u(t-1)后者是宽度 1 秒的矩形窗。代码syms t tau assume(t, real); x_sym (tau) exp(-tau) * heaviside(tau); % x(τ) e^(-τ)u(τ) h_sym (tau) heaviside(tau) - heaviside(tau - 1); % h 是宽度 1 s 的矩形窗 y_sym int(x_sym(tau) * h_sym(t - tau), tau, -inf, inf); y_sym simplify(y_sym); fplot(y_sym, [-1, 3], LineWidth, 1.5); grid on; xlabel(t / s); ylabel(y(t));参数说明assume(t, real)告诉符号引擎t是实数。不加这一步化简时可能保留abs或sign的分支fplot画出来波浪起伏报告里没法解释。heaviside是单位阶跃函数作用是在τ方向上自动截断积分区间因此int的上下限可以放心写±Inf不需要手工分段换限。int(..., tau, -inf, inf)的积分变量必须是τ。如果写成对t积分卷积定义就错了结果会变成一个常数这是新手最容易犯的错。simplify的目的是把一路带下来的heaviside嵌套压缩成分段表达式让fplot画起来更快也方便后面取数值。如果int返回很长一段piecewise不要在实验报告里整段复制。正确的做法是直接fplot出图形需要和数值法比较时用double(subs(y_sym, t, 0.5))取某个点的值。解析表达式长不长不重要能画能对比才是实验的目的。2.3 符号函数参数表和三个易错点常用调用作用本实验易错点syms t tau声明两个符号变量同一个脚本里不能再写t 0:0.1:2会把符号变量覆盖掉heaviside(τ)单位阶跃构造截断函数heaviside(0) 0.5单点值没有物理意义画图时看左右极限int(expr, τ, -inf, inf)对 τ 求卷积积分积分变量与输出变量搞混结果会变成常数piecewise(cond1, expr1, ...)分段定义信号int返回的分段结果不必强行合并保持piecewise就可以fplot(y, [a b])符号函数绘图自动切分奇点采样比plot更适合带heaviside的曲线三个实际会遇到的问题集中说一下。第一符号计算最让人头疼的错误不是公式写错而是变量被覆盖。常见流程是先用syms t求卷积接着写t -2:0.001:5去画图再返回去修改前面的卷积代码此时t已经不是符号变量int报错或者返回奇怪结果。建议把符号积分单独放一个脚本或者画完图立刻用clearvars t清理再继续符号运算。第二heaviside(0)返回 0.5这是 MATLAB 符号引擎的约定。卷积结果在t 0处如果是跳跃点解析表达式里那一点的值不重要画图时fplot会自动补一条竖线。实验报告里不要写“在零点有值”要写“t 0 时为零t ≥ 0 时按右极限取值”。第三int对某些分段组合不会化简成漂亮的piecewise而是返回嵌套的heaviside表达式。这种情况先simplify如果还不行就用subs(y_sym, t, 0.3)取几个点验证数值是否符合物理。数值对得上就直接画图不需要把时间耗在“凑教科书公式”上。提示符号积分是“用来判断对不对”的不是唯一的交付结果。真正画图快、改参数方便的是下一章的conv离散实现。3. 离散卷积的 MATLAB 实现conv、Ts 缩放与时轴重建3.1 为什么 conv 的结果必须乘 Ts从黎曼和推导离散采样的序列记为x[k] x(kTs)h[m] h(mTs)。连续卷积在输出时刻nTs的取值可以写成黎曼和y(nTs) ≈ Σ_k x(kTs) · h((n−k)Ts) · Ts右边括号里的求和正是两个序列的离散卷积conv(x, h)的第n个值。所以代码里conv(x, h)只完成了求和Ts是积分里的“面积微元”。漏掉Ts所有幅值都会固定缩小Ts倍。这是整个实验里出现频率最高的问题。注意两点。第一conv内部已经包含翻转和平移不要再用fliplr(h)手动反转一次手动反转的 bug 通常出现在自己写三层循环时用conv反而不会遇到。第二矩形法近似和梯形法近似在端点有差异量级是O(Ts)本实验用conv已经足够如果追求更高精度应该用下一节的trapz参考实现。3.2 最小脚本conv 之后重建输出时轴Ts 0.001; % 采样间隔决定幅值缩放和曲线精度 t -2 : Ts : 5; % 公共时间轴左右留白 x (t 0) (t 2); % 宽度 2 s 的矩形脉冲 h exp(-2 * t) .* (t 0); % 单边指数衰减信号 y conv(x, h) * Ts; % 离散卷积加上黎曼和缩放 ty (t(1) t(1)) (0 : length(y) - 1) * Ts; figure; plot(ty, y, LineWidth, 1.2); xlabel(t / s); ylabel(y(t) x(t) * h(t)); grid on;参数说明Ts 0.001表示 1 ms 采样间隔。对秒级时宽的信号这条曲线画出来已经是连续效果如果把Ts改成0.01矩形边界的转折点会明显变成折线。x和h直接用逻辑表达式生成截断函数等价于rectpuls和heaviside的采样版本不需要额外工具箱。y conv(x, h) * Ts中的* Ts是幅值正确的关键。改参数时最容易漏掉的也是这个系数。ty的起点写成t(1) t(1)依据是卷积的支撑集性质supp(x*h) supp(x) supp(h)。如果两个信号的时间轴起点不同应该写成tx(1) th(1)而不是把-4写死。0 : length(y) - 1表示卷积定义里的序号n从 0 开始。MATLAB 数组索引从 1 计数但时间轴公式里如果用1 : length(y)整条曲线会向右偏一个Ts。如果两个信号的支撑区间不在原点附近t的左右边界要留足空白。常见错误是把t定义成0:Ts:5矩形和指数都在正半轴卷积结果的负半轴部分画不出来只看到半条曲线还以为自己代码写错了。3.3 用 trapz 实现定义式作为 conv 的参考校验xs (s) (s 0) (s 2); % 用函数句柄再表达一次信号 hs (s) exp(-2 * s) .* (s 0); tOut (t(1) t(1)) (0 : length(y) - 1) * Ts; % 与 conv 版本同一输出网格 y_ref arrayfun((tt) trapz(t, xs(t) .* hs(tt - t)), tOut);这段代码对tOut里的每一个时刻执行一次数值积分xs(t) .* hs(tt-t)一行完成翻转和平移。trapz采用梯形公式与conv的矩形黎曼和存在端点差异量级在Ts附近。所以验收标准是max(abs(y - y_ref))应该在1e-3量级或更小。如果差异明显大于Ts问题出在时轴或缩放而不是算法本身。arrayfun版本慢但逻辑和积分定义一一对应适合写进实验报告作为“数值积分方法”的说明。3.4 快速自查表症状基本原因调整方法波形形状对整体幅度是理论值的 Ts 倍conv(x, h)后没乘 Ts改成conv(x, h) * Ts曲线形状对整体向右偏移一个 Ts输出序号用了1:length(y)改成0 : length(y)-1只画出一半曲线负半轴缺失公共时间轴没有从负值开始把t的起点前移conv和trapz差异很大采样间隔过大或支撑区间设计不合理缩小Ts重新检查两个信号的支撑4. 实验二配套常用信号构造、模板函数与报告验收参数4.1 常用信号在 MATLAB 里的表示法信号类型数学表达式MATLAB 写法实验用途单位阶跃u(t)(t 0)或heaviside(t)截断函数基底矩形脉冲rect((t-t0)/W)rectpuls(t-t0, W)时限信号卷积结果宽度直观三角脉冲tri(t/W)tripuls(t, W)分析和数值对比难度适中单边指数e^{-at}u(t)exp(-a*t) .* (t 0)模拟系统冲激响应冲激近似δ(t)imp zeros(size(t)); imp(abs(t)Ts/2)1/Ts第五章自检用rectpuls和tripuls来自 Signal Processing Toolbox。如果环境里没有这个工具箱用(t a) (t b)代替rectpuls用(ta)-(tb)代替阶跃组合效果完全一样。实验二里“指数 × 阶跃”的组合可以直接当成系统阶跃响应的卷积模型来理解这也解释了为什么信号与系统课程喜欢拿这个组合出题。4.2 一份可以直接交付的卷积函数模板把上一章的代码整理成函数后续换信号只改函数句柄不需要动主流程function [ty, y] cont_conv(fx, fh, t, Ts) %CONT_CONV 在公共时基 t 上完成两个连续信号的离散卷积 % fx, fh : 信号函数句柄形如 (t) ... % t : 公共时间轴应覆盖两个信号的支撑区间 % Ts : 采样周期决定幅值缩放与精度 x fx(t); h fh(t); if length(x) ~ length(h) error(两个信号必须写在同一个公共时基上); end y conv(x, h) * Ts; ty (t(1) t(1)) (0 : length(y) - 1) * Ts; end调用示例fx (t) rectpuls(t - 0.5, 1); % 中心在 0.5、宽度 1 的矩形 fh (t) tripuls(t, 2); % 宽度 2 的三角脉冲 t -2 : 0.001 : 3; [ty, y] cont_conv(fx, fh, t, 0.001); plot(ty, y); grid on;函数签名的设计思路是把“信号生成”和“卷积计算”拆开。做实验二的不同小题时真正要改的只有fx、fh、t这三行卷积核心代码保持不动。这样做的好处是几个人合做实验只要统一Ts结果之间的可比性就很强。4.3 报告验收参数表实验报告里除了贴图还应该给出一个可复现的参数表。下面四列建议直接做成表格放进 doc参数项计算方法通过标准面积校验abs(trapz(ty,y) - trapz(t,x)*trapz(t,h))小于1e-2量级输出时宽ty(end) - ty(1)等于两个输入时宽之和误差 1 个 Ts解析对比max(abs(y - y_sym_grid))小于Ts量级峰值位置[~, idx] max(y); ty(idx)与理论峰值时刻一致面积校验的原理是连续卷积的积分性质卷积结果的面积等于两个信号面积的乘积。这个性质对任何一组实验信号都成立写进报告比单纯说“图像看起来一致”有说服力得多。5. 提交前多跑一条冲激自检同时验证 Ts 与时轴5.1 在采样网格上构造单位冲激连续卷积有一个性质δ(t) * h(t) h(t)。离散实现里“单位冲激”不能真的只放一个高度为 1 的点那样面积变成Ts卷积结果整体就会缩小Ts倍。正确做法是把一个采样格子的高度设为1/Ts保证这一格的总面积是 1。Ts 0.001; t -2 : Ts : 5; h exp(-2 * t) .* (t 0); % 被测信号 imp zeros(size(t)); imp(abs(t) Ts/2) 1 / Ts; % 一个格子宽度面积归一化为 1 y_p conv(imp, h) * Ts; ty_p (t(1) t(1)) (0 : length(y_p) - 1) * Ts;5.2 一条 max 命令暴露三类错误把卷积结果重新对齐到原始时间轴t上再和h逐点比较idx round((t - ty_p(1)) / Ts) 1; err max(abs(y_p(idx) - h));理想情况下err应该落在1e-12量级这是浮点舍入误差而不是建模误差。如果err明显偏大可以根据数值快速定位问题err在1e-3量级imp没有除以Ts冲激面积错成了Tserr在1e3量级conv结果没有乘Ts幅值比例整体错掉err和h的幅值同量级imp的1/Ts和卷积的*Ts两个系数都丢了或者时轴重建公式里t(1)t(1)写成了别的数。这段自检代码不依赖任何工具箱而且运行时间极短。把它放在实验脚本最末尾作为提交前的“最后一道闸门”比人工看图可靠得多。5.3 把三种结果拼到实验报告里最终的报告建议生成两个图第一个图把符号积分和conv * Ts画在一起用图例标注“int 闭式解”和“离散卷积”让老师一眼看到两条曲线重合第二个图单独放冲激自检把y_p(idx)和原始h用不同线型叠加旁边标注err数值。实验报告里的参数表补充一行“冲激自检误差”填err的值。这一行的好处是即使Ts换成了0.002或者0.005只要误差仍在1e-12量级就说明代码的尺度正确、时轴正确。后续换任意一组信号从头到尾只需要改fx、fh和t三行自检代码原样保留即可。本文还有配套的精品资源点击获取