MATLAB谐波仿真:从复指数到傅里叶级数的信号分析

发布时间:2026/10/20 1:31:52
MATLAB谐波仿真:从复指数到傅里叶级数的信号分析 简介面向电子工程、通信与信号处理领域的学生、工程师及入门者系统讲解MATLAB中信号仿真与谐波分析的核心方法涵盖正弦信号和复指数信号的连续时间与离散时间表示并利用傅里叶级数展开剖析谐波分量与周期性的内在联系。资源为单份PDF文档约190KB内容高度凝练包含可复现的MATLAB代码片段与实验步骤。已有1273人学习适合作为信号与系统、数字信号处理课程的配套资料。从实验角度资源演示了如何用两个共轭复指数构造正弦序列、利用subs设定周期参数、分图绘制复指数信号实部与虚部并总结谐波分量角频率为基波整数倍、周期信号周期等于各谐波周期最小公倍数等结论还结合弹簧振子、单摆等物理场景说明正弦信号的应用帮助读者在仿真中加深对周期分解和复指数表达的理解。1. 谐波仿真为什么总绕不开复指数MATLAB 正弦信号的那点本质做信号仿真的人迟早都会面对一个疑惑明明想画一条正弦波代码里却满是exp()明明教材讲傅里叶级数用的是三角函数真正写出来却是一排复指数。这份实验资源把离散正弦信号、连续正弦信号、复指数信号的绘制与分析串成一条线用stem、subplot和符号替换三组代码验证了谐波分析里最关键的结论——周期信号可以分解为谐波分量的和而谐波分量天然适合用复指数表达。整份材料适合刚接触信号与系统、对复指数与三角函数关系还不熟的人也适合那些工作中需要快速恢复 MATLAB 绘图手感、准备转向傅里叶级数和频谱分析的工程师。2. 正弦信号绘制从复指数换算式到 stem 出图的完整落地2.1 正弦与复指数之间的换算原理正弦信号能拆成两个共轭复指数的差再除以两倍虚数单位这件事不是 MATLAB 的某种奇技淫巧而是欧拉公式的直接推论。把exp(jθ)展开成cosθ j*sinθ再把exp(-jθ)展开成cosθ - j*sinθ两者相减之后实部和余弦项全部抵消只剩下2j*sinθ于是得到sinθ (exp(jθ) - exp(-jθ)) / (2j)式子里的j是虚数单位MATLAB 里写作1j或j都能识别。这个换算最大的价值在于它把“三角函数振荡”转换成了“复平面上两个旋转矢量的合成”。当信号频率升高时指数里的角度变化更快图上看到的就是矢量旋转速度加快而不是像sin函数那样只是一个数值列表。这种视角直接影响后续对谐波关系的理解——周期信号被拆成不同旋转速度的复指数分量之和每个分量的角频率是基波角频率的整数倍这正是傅里叶级数的核心。实验里用到的信号是x sin(πn/4)角频率是π/4对应离散周期 8 个采样点。把θ πn/4代入欧拉公式就得到实验文档里的那行复指数表达式。理解这一步之后再看代码就不再是“背公式”而是知道每条指令在算什么。2.2 离散正弦序列stem 绘制三步走离散正弦序列的绘制实验文档给出了一个很紧凑的代码段真正要落地的步骤可以拆成三步。n 0:32; % 采样索引0 到 32共 33 个点 x (exp(1j*pi*n/4) - exp(-1j*pi*n/4))/(2*1j); % 复指数差除以 2j得到 sin(pi*n/4) stem(n, x); % 离散序列用茎叶图第一步是生成索引向量n。这里0:32的默认步长是 1对应离散时间信号在每个整数采样点上的取值如果只有一个周期 8 个点写成0:7够用但实验里画 33 个点是为了看到 4 个完整周期方便肉眼确认周期性。多数教材习惯写n[0:32]加不加方括号结果一样我一般直接去掉。第二步是计算序列值。exp(1j*pi*n/4)生成一个复数向量exp(-1j*pi*n/4)是它的共轭两者相减得到一个纯虚数序列再除以2*1j就还原成实数正弦值。注意分母一定要写成(2*1j)如果写成/2*jMATLAB 会按从左到右的优先级先除 2 再乘 j原本的实信号就变成了实部恒为 0 的虚信号后面第 5 章还会专门展开这个坑。第三步是用stem画图。它只画离散点每根竖线顶端带一个小圆点最能体现“采样序列”的含义。如果这里误用plot(n, x)会得到一条连续折线虽然波形轮廓相似但表达的是连续时间信号和实验主题不符。代码跑完后图上应该能清楚看到 4 个完整周期的正弦形状周期是 8 个采样点。提示stem的默认坐标轴范围会自动适应数据如果点与点太密可以用xlim([0 20])只显示前几个周期。2.3 连续正弦信号符号变量与周期替换连续时间正弦信号的绘制思路不一样。离散序列直接计算数值就行而连续信号实验文档选择先构造符号表达式再替换周期参数最后出图。syms t T; % 声明符号变量 t 和 T x (exp(1j*pi*t/T) exp(-1j*pi*t/T))/2; % 余弦信号的复指数表示cos(pi*t/T) x5 subs(x, T, 5); % 把周期 T 替换成 5 fplot(x5, [0, 10]); % 绘制连续波形横轴范围 0 到 10这段代码里syms t T声明了两个符号变量x是以t为自变量的符号表达式。因为余弦函数cos(πt/T)等于两个共轭复指数的平均值所以这里用加号而不是减号这是与正弦表达式最容易混淆的地方。subs(x, T, 5)执行符号替换把表达式里所有T换成数值 5。参数顺序很关键第一个参数是原表达式第二个参数是被替换的符号第三个参数是新值。替换后的x5变成cos(πt/5)角频率是π/5周期是 10 秒。所以fplot的横轴范围取[0, 10]正好画出一个完整周期如果设为[0, 20]就能看到两个周期。老版本 MATLAB 用ezplot(x5, [0, 10])新版大多能用但会提示兼容问题直接换fplot更干净。运行之后得到的是一条光滑的余弦曲线起点在 1过零点在t 2.5和t 7.5这些细节可以用来反向验证周期是否正确。符号替换的价值在于不需要为每个周期重新写一遍函数表达式只要修改subs的第三个参数就能快速对比不同周期下的波形这对后面理解“周期只和角频率有关”非常有帮助。3. 复指数信号可视化实部虚部分离绘制与时间轴设定3.1 为什么要拆开实部和虚部复指数信号y(t) exp((1 j10)t)同时包含幅度变化和相位旋转。直接对复数做plotMATLAB 会把横轴当实部、纵轴当虚部画成一条在复平面上绕圈的轨迹看不出幅度随时间增长的趋势也看不出振荡频率是多少。所以实验中把实部和虚部分别沿时间轴展开一上一下两张子图才能同时读到两类信息。从数学上看exp((1 j10)t)可以拆成e^t乘以(cos10t j*sin10t)。实部是e^t*cos10t虚部是e^t*sin10t。两者共享同一个包络e^t只是相差 90 度相位。也就是说两张子图的形状完全一致但虚部比实部滞后四分之一个周期。这一点在绘制结果上应当能直接看出来。3.2 双轴子图的绘制步骤与参数选择t 0:0.01:10; % 时间轴步长 0.01 秒共 1001 个采样点 y exp((1 1j*10) * t); % 复指数信号实部系数 1虚部角频率 10 rad/s subplot(2, 1, 1); % 上下布局的上半部分 plot(t, real(y)); % 画实部 grid on; % 加网格辅助读数 subplot(2, 1, 2); % 上下布局的下半部分 plot(t, imag(y)); % 画虚部 grid on;时间轴0:0.01:10的步长是 0.01 秒频率 10 rad/s 对应周期约 0.628 秒每个周期内大约有 63 个采样点画正弦振荡足够平滑。如果步长改成 0.1 秒每个周期只剩约 6 个点波形会明显跑偏如果改成 0.001 秒视觉差异不大但向量长度变为 1 万个点没必要。subplot(2,1,1)的意思是两行一列布局当前绘制位置在第一格subplot(2,1,2)切到第二格。real(y)和imag(y)分别提取复数的实部与虚部。参数上最值得留意的是指数项里的实部系数 1。它让整个波形以e^t的速度包络增长画到 10 秒时幅度已经超过两万图像上下边缘会被截断这属于正常现象。如果只是想观察振荡细节把实部系数改成负数比如exp((-1 1j*10)*t)波形会衰减十个周期内都能保持清晰边界更适合做周期测量。3.3 从图读取角频率过零点反推画完图之后建议顺手做一次反推验证。实部是e^t*cos10t它的过零点由cos10t 0决定相邻两个过零点的间隔是半周期 π/10约 0.314 秒。在图上用光标或ginput量取几个过零点取平均间隔 Δ则角频率 ω π/Δ。这个步骤看似多余却能立刻发现参数有没有设置错。比如有人把频率参数误写成exp((1 1j)*t)角频率变成 1 rad/s周期约 6.28 秒在 10 秒窗口里只能看到 1.6 个周期量取过零点后会得到 Δ ≈ 3.14 秒反推出 ω ≈ 1。看到这个数字就能意识到和预期不符。读图是复指数信号仿真里最值得养成的习惯它把抽象的“角频率”变成了坐标轴上的可量距离。4. 谐波关系的周期分析从最小公倍数到基波角频率的推导4.1 谐波分量周期关系表谐波关系的本质是频率的整数倍。设基波角频率为 ω₀那么 k 次谐波的角频率是 kω₀。根据连续时间信号周期公式 T 2π/ω可以直接列出各次谐波的周期关系。谐波次数 k角频率周期 T_k与基波周期 T₁ 的关系1ω₀2π/ω₀T₁22ω₀π/ω₀T₁/233ω₀2π/(3ω₀)T₁/3kkω₀2π/(kω₀)T₁/k这张表说明一个关键事实各次谐波的周期不是任意值而是基波周期的整数分之一。画在同一时间轴上时基波刚好走完一个周期二次谐波已经走了两个周期三次谐波走了三个周期所以它们叠加后的信号在基波周期处必然回到同一起点。4.2 最小公倍数为什么等于基波周期实验文档的结论是“周期信号的周期等于各个谐波分量的周期的最小公倍数”这句话在连续时间下可以严格推出来。设基波周期 T₁ 2π/ω₀各谐波分量周期为 T₁/k。求这组数的最小公倍数时因为 T₁ 本身是其中最大的数而且每个 T₁/k 乘以 k 都能回到 T₁所以 T₁ 就是它们共同的整数倍周期也就是最小公倍数。有一个常见误用要提醒有人看到“最小公倍数”就把 k 次谐波周期乘起来再找公倍数得到一个大得离谱的周期。实际上谐波分量周期分母里的 k 就是“在一周期内走了几圈”的意思公倍数只取基波周期不需要额外放大。验证方法是把 1、2、3 次谐波叠加波形在 T₁ 处完全重合而在 T₁/2 处因为三次谐波滞后半周期而无法对齐。但这里要区分离散时间情形。离散序列的周期必须是整数sin(πn/4)的周期是 8sin(2πn/4)的周期是 4sin(3πn/4)的周期是 8因为 3 与 8 互质三者的最小公倍数依然是 8。也就是说离散情况下不能直接用 T₁/k 表示第 k 次谐波的周期而要先算整数周期再取最小公倍数。大多数谐波次数与 8 互质时公共周期仍然等于基波周期。4.3 用代码验证合成信号的公共周期理论推导之后最好在 MATLAB 里做一个可视化验证。把基波、二次谐波、三次谐波叠加起来看合成序列是否以基波周期为重复周期。n 0:32; % 采样索引覆盖 4 个基波周期 x1 sin(pi*n/4); % 基波角频率 pi/4周期 8 x2 sin(2*pi*n/4); % 二次谐波角频率 pi/2周期 4 x3 sin(3*pi*n/4); % 三次谐波角频率 3*pi/4周期 8 y x1 x2 x3; % 三种分量直接叠加 stem(n, y); % 观察合成序列的周期 grid on;运行结果里合成信号在第 8、16、24、32 个采样点处的相位完全一致说明公共周期确实等于基波周期 8。代码中x2 sin(2*pi*n/4)也可以写成sin(pi*n/2)角频率翻倍序列每 4 个点循环一圈x3的频率是基波的 3 倍但因为 3 和 8 互质它的离散周期又回到 8这正是离散谐波与连续谐波最明显的差异点。这个差异在实验文档中虽然没有展开但实际仿真时直接影响你给信号定周期的方式。5. 信号仿真避坑采样步长、括号优先级与符号替换的五个翻车点5.1 离散信号步长设置错误stem 图糊成一片现象把n 0:32改成n 0:0.1:32后stem(n, x)画出来不是稀疏的点列而是一把密密麻麻的“梳子”周期完全看不出来。原因离散时间信号的索引只能是整数。步长 0.1 并不代表“采样更细”而是强行在非整数位置构造了不存在的采样点导致同一个周期里塞进去几十个点视觉上全部重叠。解决离散序列一律用n 0:32这种整数步长。如果想看包络形状可以改用plot(n, x)并配合marker选项想强调每个采样点stem依然是最合适的选择。5.2 复指数除法漏括号正弦变负向现象代码写成x (exp(j*pi*n/4) - exp(-j*pi*n/4))/2*j结果画出的序列振幅为负看起来像反向正弦。原因MATLAB 的乘除运算优先级相同从左到右计算/2*j实际是先除以 2 再乘以 j整个式子变成a/2*j而正确的数学含义是除以2j。一个括号之差实信号变成虚信号正弦方向整个反转。解决分母统一写成(2*j)与实验文档保持一致。如果不习惯括号也可以写成/2/j等于连续除以 2 再除以 j结果和除以 2j 相同。最稳妥的写法是/(2*j)一眼就能看出分母的构成。5.3 subs 参数顺序颠倒周期替换失败现象执行subs(x, 5, T)后画图区空白或者返回的表达式里仍然带着符号 T。原因subs的调用格式是subs(expr, old, new)第二个参数必须是表达式里已有的符号变量第三个参数才是要替换进去的值。把数字 5 放在第二位MATLAB 会尝试把数字 5 当作符号出现的位置替换成 T自然失败或得到原式。解决写成subs(x, T, 5)。如果重复替换多个参数可以用subs(x, {T, omega}, {5, 3})的元胞数组形式。新版 MATLAB 里也可以跳过符号替换直接定义匿名函数fplot((t) cos(pi*t/5), [0 10])。5.4 ezplot 在新版本里的兼容问题现象原样复制实验代码ezplot(x5, [0, 10])图形能出来但命令行反复提示该函数即将移除或者推荐改用fplot。原因MATLAB 从较新版本开始逐步弱化ezplot绘图底层已经切换到新接口兼容函数还在但不再作为推荐路径。解决直接替换成fplot(x5, [0, 10])用法几乎相同。注意fplot需要符号表达式或函数句柄传数值数组进去会报错如果x是字符串形式构造的符号表达式先syms t T再用fplot即可。5.5 谐波周期“最小公倍数”理解错位现象某开发者按“所有谐波周期的乘积再取最小公倍数”计算得出周期是基波周期的好几倍与仿真波形对不上。原因连续时间下 k 次谐波周期是基波周期 T₁ 的 k 分之一它们的公共周期就是 T₁不需要放大。离散时间下情况稍复杂比如 3 次谐波的分频周期 8/3 不是整数不能直接参与基于整数的最小公倍数计算要先按整数周期重新核算。解决连续信号直接记住 T 2π/ω₀离散信号先计算每个分量各自的整数周期再对所有整数周期取最小公倍数。实践里最可靠的办法还是画图把合成信号平移一个基波周期看是否完全重合。6. 从谐波仿真反推傅里叶级数用系数叠加验证周期特性掌握正弦和复指数信号的绘制之后可以往前再走一步把“信号能分解成谐波分量”这个结论反过来用。给定一个目标波形例如标准方波它的傅里叶级数只含奇次谐波第 k 次谐波的幅值系数是 4/(kπ)。在 MATLAB 里把前几项谐波叠加起来就能直观看到级数逼近的过程。t 0:0.01:2; % 时间轴覆盖两个周期 w0 2*pi; % 基波角频率对应周期 1 秒 x zeros(size(t)); % 初始化为零向量 for k 1:2:9 % 只取 1, 3, 5, 7, 9 次谐波 x x (4/pi) * (1/k) * sin(k*w0*t); % 累加方波谐波分量 end plot(t, x, LineWidth, 1.5); % 画叠加后的波形 grid on; xlabel(t (s)); ylabel(x(t));代码里的k 1:2:9是奇数步进保证只叠加奇次谐波(4/pi) * (1/k)是方波傅里叶系数的幅值1/k 表示谐波次数越高贡献越小。叠加到 9 次谐波时波形已经明显呈现方波轮廓但边缘处会出现小幅过冲这就是吉布斯现象属于截断固有产物不是代码错误。把终止值改成99再运行边沿会更陡但过冲幅度并不会消失。我通常会在跑完这个叠加后顺手把第一项单独画出来对比只有基波时波形是一条标准正弦幅值约 1.27加上三次谐波后顶部开始变平加到五次以上才真正“像方波”。这个过程比任何公式都更能说明“周期信号由谐波叠加而成”的含义。有一次我仿真时把 1/k 漏了结果高次谐波幅值过大波形顶部出现剧烈震荡检查了好一会儿才发现是系数少写。从那以后我每做谐波叠加仿真都会先手写一遍前几项系数再对照代码里的(1/k)逐个核对最后才用plot验证周期。这个习惯帮我避免过好几次低级错误希望帮到你。本文还有配套的精品资源点击获取