差分方程的迭代解法:递推法

各位同学,今天我们来聊聊差分方程最直接的解法——递推法。

说实话,我刚接触差分方程时,觉得这东西挺抽象的。后来在做一个数字滤波器项目时,发现递推法其实就是「一步一步往前推」的过程。你想想看,给定初始条件,按照方程规则,一步步算出后面的值,这不就是我们平时做事的逻辑吗?

递推法的核心思想

递推法,说白了就是「已知过去,推知未来」。

对于一个 n 阶差分方程:

y[k] + a₁y[k-1] + ... + aₙy[k-n] = b₀x[k] + b₁x[k-1] + ... + bₘx[k-m]

我们可以把它改写成:

y[k] = -a₁y[k-1] - ... - aₙy[k-n] + b₀x[k] + b₁x[k-1] + ... + bₘx[k-m]

嗯,这里要注意:y[k] 只依赖于过去的值。只要我们知道初始条件 y[0], y[1], ..., y[n-1],就能一步步算出 y[n], y[n+1], ...

关键点:递推法不需要解特征方程,不需要求通解,直接数值计算。适合计算机实现,也适合手算小规模问题。

迭代公式的推导

我习惯把迭代公式写成标准形式。以一阶差分方程为例:

y[k] + a y[k-1] = b x[k]

移项得到迭代公式:

y[k] = -a y[k-1] + b x[k]

你看,这个公式告诉我们:当前输出 = 系数 × 上一个输出 + 系数 × 当前输入

对于二阶情况:

y[k] + a₁y[k-1] + a₂y[k-2] = b₀x[k] + b₁x[k-1]

迭代公式为:

y[k] = -a₁y[k-1] - a₂y[k-2] + b₀x[k] + b₁x[k-1]

我曾经在做一个音频回声消除项目时,就是用这种二阶递推来模拟房间脉冲响应的。当时调试了好久才发现是初始条件设错了——嗯,这个坑后面会讲。

初值条件的作用

初值条件为什么重要?

你想想看,递推公式就像一台机器,你得给它「喂」初始数据,它才能开始运转。没有初值,递推就无从开始。

对于 n 阶差分方程,我们需要 n 个初始条件:

  • 一阶方程:需要 y[0] 或 y[-1]
  • 二阶方程:需要 y[0] 和 y[1](或 y[-1] 和 y[-2])
  • n 阶方程:需要 n 个连续的初始值

避坑指南:我曾经在项目中把初始条件设成了全零,结果系统响应完全不对。后来发现,对于某些系统(比如积分器),初始条件不能随意设为零。一定要根据物理意义来设定。

数值计算示例

光说不练假把式。我们来看一个具体例子。

例:已知差分方程 y[k] - 0.5y[k-1] = x[k],初始条件 y[0] = 1,输入 x[k] = 1(k ≥ 0)。求 y[1], y[2], y[3]。

解:

迭代公式:y[k] = 0.5y[k-1] + x[k]

k 计算过程 y[k]
0 已知 1
1 y[1] = 0.5 × 1 + 1 1.5
2 y[2] = 0.5 × 1.5 + 1 1.75
3 y[3] = 0.5 × 1.75 + 1 1.875

你看,y[k] 逐渐趋近于 2。这个系统是稳定的,因为系数 0.5 的绝对值小于 1。

小技巧:手算时建议列个表格,k 从 0 开始,一行一行往下算。不容易出错,也方便检查。

递推法的流程图

下面我用 SVG 画了一张递推法的流程图,帮你理清思路:

递推法求解差分方程流程图 开始 输入初始条件 y[0], y[1], ..., y[n-1] 设置 k = n 计算 y[k] = -a₁y[k-1] - ... - aₙy[k-n] + b₀x[k] + ... k 达到目标? 结束 k = k + 1

递推法的优缺点

我个人觉得,递推法最大的优点是直观。你不需要懂什么 Z 变换、特征方程,只要会加减乘除就能算。

但缺点也很明显:

  • 只能得到数值解,得不到解析表达式
  • 误差会累积,步数越多误差越大
  • 计算量大,如果要算 1000 步,手算得累死

我的建议:小规模问题(几步到几十步)用手算递推,大规模问题用 MATLAB 或 Python 编程实现。我在项目中通常先用递推法验证一下思路,再用解析法做精确分析。

总结

递推法,说白了就是「一步一步来」。

记住三个要点:

  1. 迭代公式要写对——移项时注意符号
  2. 初值条件要设对——缺一个都不行
  3. 计算过程要仔细——一步错,步步错

嗯,今天就到这里。下次我们聊 Z 变换法,那才是真正的高效工具。


公众号:蓝海资料掘金营,微信deep3321