DLSODA:自动切换 Adams 与 BDF 的常微分方程求解器(二)
DLSODA:自动切换 Adams 与 BDF 的常微分方程求解器(二)
[TOC]
LSODA方法中所谓的“自适应”,其实包含以下三个方面:
- 步长自适应
- 阶数自适应
- 方法族自适应
在上一篇文章中,我们已经提到LSODA使用的两种方法,但是还未提及它在实际计算的时候是如何自适应地切换的。在这篇文章中,我们将分别来讲一下它是如何做到这三者的自适应的。
4. 从定步长公式到自适应多步法
在上一篇文章的第 3 节,我们从等距节点出发,推导了定步长 Adams 与 BDF 公式。不过在实际求解的过程中,定步长所带来的缺陷是十分明显的。我们知道,实际 ODE 的时间尺度通常并不均匀。解在某些区间可能十分平滑,在另一些区间却可能出现快速过渡。如果始终使用同一个步长,就会面临以下两种问题:
- 若步长按最困难区间选取,那么在平滑区间会进行大量没有必要的计算;
- 若步长按平滑区间选取,那么进入快速变化区间后,局部误差可能超过容差,甚至发生迭代或稳定性崩溃。
从原则上说,一个可接受的步长至少同时受到精度与稳定性两方面的约束(这点我们在上一篇文章中已经举过例子了):
其中
其中
4.2 变步长给多步法带来的额外困难
我们知道 Adams 和 BDF 是多步法,当前公式依赖若干历史节点的信息。令
一旦
例如,对 Adams 方法令
并用 Lagrange 基函数
插值历史导数,则相应积分权重为
因此一般变步长 Adams 公式中的
BDF 也有同样现象。以
其中
例如令
当
上面的推导描述了将定步长的多步法推广到变步长的基本思想。可以看到,由于步长的改变,公式中的系数也会发生相应的修改。但是如果每次计算一个step都需要按照上面的方法重新计算每一个历史节点的系数,可想而知这样的效率是十分低下的。所以LSODA采用下面所介绍的局部多项式和Nordsieck向量,来避免每次改变步长后,重新处理不等距历史节点和计算整套权重。
4.3 局部多项式与 Nordsieck 向量
假设当前内部时间为
把它们组成 Nordsieck 向量
等价地,引入无量纲变量
局部解可以表示为
对局部多项式 (Q(x)),有
而对 (x) 求导时
因此:
- (Q(-1)) 表示 (y_n);
- (Q’(-1)) 表示 (hf_n);
- (Q’(-2)) 表示 (hf_{n-1});
- (Q’(0)) 表示新时刻的 (hf_{n+1})。
在这个局部多项式中,我们巧妙地利用了局部多项式来储存历史信息,用修正的方式来消除每一步步长不相等的影响。
4.4 Nordsieck向量在变步长下的变换
若此时新的步长为
定义新尺度变量
因为
所以同一条多项式可以写成
因此
其中
注意到此时的时间中心还是 (t_n),接下来我们就需要进行
令
则
把它重新按
其中
至此我们就得到了在变步长情况下,多步法中历史节点的Nordsieck向量储存方式和更新方法。
4.6 Pascal平移的公共预测及其校正
预测多项式在新时刻给出
但预测值一般不严格满足微分方程(接下来我们会看到,这里的 Pascal 平移给出的是公共预测。而之后的修正,将体现出Adams和BDF两种算法的差别)。ODE要求
因此定义新时刻的缩放导数误差
若只修改一阶导数,新的多项式就会与原有的历史条件不相容(在下面一小节可以更具体地看到)。正确做法是选择一个标量校正多项式
并令
于是各阶系数统一更新为
特别地,校正后的解是
由于
也就是
4.7 Adams 的校正多项式
(q) 阶隐式 Adams–Moulton 方法,本质上用以下导数值构造一个 (q-1) 次导数插值多项式:
在 (x) 坐标中,这些节点是
然后将这个导数插值多项式从 (t_n) 积分到 (t_{n+1}),因此还需要一个积分起点:
所以一个 (q) 阶 Adams 局部解多项式由以下 (q+1) 个条件确定:
以及
次数为 (q) 的多项式有 (q+1) 个系数,恰好由这些条件唯一确定。
经过 Nordsieck–Pascal 预测后,我们得到
它在新时刻给出预测值和预测导数:
在固定步长原型中,这条预测多项式仍然携带旧的 Adams 历史条件:
问题发生在新时刻的导数项:
我们并不能保证这两者是相等的,因为我们并没有
于是可以定义所需的新导数改变量
但是如果我们只把一阶系数改成
相当于令
但在历史节点 (x=-j) 处,
会破坏已有的历史插值条件。
因此,校正不能只改变一个系数,而必须沿某个完整多项式方向进行:
这里的 (l(x)) 要完成两件事:
- 在新时刻把导数增加 (a);
- 在历史节点不改变 Adams 所依赖的信息。
由于我们的积分起点
所以必须有
Adams 使用历史导数需要保持不变
要求校正后不改变这些导数:
所以必须要求
在新时刻把导数增加 (a),要求
所以必须有
利用上面对于
所以它一定具有形式
再使用归一化条件 (l’(0)=1):
因此
最后,导数只能确定 (l(x)) 到一个积分常数。利用
得到
这就是 Adams 校正多项式。
4.8 BDF 的校正多项式
在固定步长原型中,
满足这些零点条件的多项式必为常数倍的
再用
得到
这就是 BDF 校正多项式。
4.9 算法的等价性
看到这里或许你会有一个疑问
在这一套预测-校正算法中,我没有看到我们使用Lagrange多项式对f或者y进行预测,全程都是Q在预测,而Q的建立是根据Taylor展开得到的。那我们是如何保证我们这一套预测-校正算法最终给出的每个历史节点的权重,与我们常规定步长所使用的权重是一致的呢?
其根本原因在于,我们都在尝试用一个
Lagrange 形式:
Newton 形式:
Nordsieck 形式:
这三者只是同一多项式的不同坐标表示:
5. 隐式校正方程的求解
上一节把 Adams 与 BDF 都归结为同一个非线性方程
预测值对应初始猜测
因此接下来我们的问题就变成了怎样求解
5.1 函数迭代:便宜但有收敛半径限制
直接把校正方程写成不动点形式:
设精确校正为
在解附近线性化,得到
其中
所以局部收敛要求近似满足
其中
对非刚性问题,精度允许的步长通常使
5.2 Newton 与 chord 迭代:消除简单不动点限制
对
第
然后更新
严格 Newton 法在每次迭代都重新计算
对
这样做牺牲了严格 Newton 法的二次收敛,但把最昂贵的 Jacobian 构造和矩阵分解摊销到了多个步骤上。对于刚性问题,这通常远比把
5.3 校正收敛的判据
对于上面所讲的函数迭代法,我们需要确定迭代停止的判据。换句话说,就是我们何时认为这个迭代收敛了。为此,我们先定义两个容差。对解的第
其中
二者共同定义第
因此,对一个误差或校正向量
表示第
令
并定义加权最大范数
因此
现在设第
若迭代已经进入线性收敛区,可以用
估计收敛率。若
更严格地说,若从当前迭代开始存在某个
那么当前迭代值与真正不动点
这相当于给出了尾部校正量增量的上限,我们需要使用这个估计量来判断迭代的进度。
设
若
如果经过若干次迭代后仍不能满足这个条件,数学上通常有两类原因:对于简单函数迭代,可能是
5.4 至此得到一个完整的单步算法
暂时不考虑误差控制和方法切换,一个时间步已经可以完整描述为:
- 若步长改变,按
缩放 Nordsieck 各列; - 用 Pascal 平移得到
; - 以
为初值求解校正方程; - 用
更新局部多项式; - 将
作为下一步的历史。
剩下的问题就是:校正量多大才可以接受本步?如果过大,应当把步长缩小多少?这就需要我们进行局部截断误差估计。
6. 局部误差估计
所谓的局部截断误差指的是,假设进入当前时间步的所有历史值都精确时, 数值方法在这一个时间步中产生的误差。这是我们判断是否要更改模型步长及其阶数的重要依据,所以我们需要想方设法来估计它。
6.1 利用校正量估计局部截断误差
对于
类似地,局部截断误差也可以写为
只要
常数
以二阶 Adams—Moulton 梯形公式为例。在固定步长且历史数据精确时,预测导数是对
所以导数校正量为
而梯形公式的局部截断误差为
因此
这就说明,我们可以通过预测导数校正量来估计局部截断误差,因此记
作为本步的局部误差估计。
第 5.3 节定义的加权最大范数不仅用于判断非线性校正是否收敛,也用于判断本步的局部截断误差是否可以接受。定义当前
注意到在前面我们定义了一个
6.3 接受或拒绝一个时间步
得到
一个时间步需要同时通过两项测试:
- 隐式校正迭代收敛;
- 局部误差指标不超过 1。
前者保证离散方程已经被足够准确地求解,后者保证这个离散方程本身的截断误差足够小。二者缺一不可。
7. 由误差模型选择步长和阶数
第 4 节解释了为什么需要改变步长,以及改变步长后怎样重标度 Nordsieck 历史量。在上一节中我们也介绍了如何通过导数校正量来估计局部误差。那么接下来就来讲讲我们是如何通过误差来选择步长和阶数的。
7.1 当前阶数下的理想步长
为了同时讨论不同阶数,记
一个
希望下一步满足误差边界
实际选择时通常乘一个安全因子
对当前的
所以
7.2 阶次的选择
需要说明的是,阶次的改变并不是任意的。我们并不希望阶次发生太大的变化,所以我们只在
降到 阶
当前局部多项式为
若降到
它具有
相应的无量纲误差指标与候选步长倍率为
指数为
保持 阶
保持当前阶数时,直接使用由校正量得到的估计:
升到 阶
这个量没有直接包含在当前只到
于是存在只依赖方法族和阶数的常数
相应地,
升阶估计只有在已经积累了足够的平滑历史信息时才可靠。如果尚不能得到可信的
比较三个候选方案
最终比较
选择预计允许最大下一步长的阶数。
一般情况下,升阶其实并不一定是最优的选择。提高阶数的好处是误差随
- 更长的历史建立时间;
- 对解的光滑性更高的要求;
- 更小或形状更不利的稳定区域;
- 更多寄生模态与舍入误差影响;
- 阶数和步长改变后更复杂的历史调整。
因此当解刚经历快速暂态、右端不够光滑或步长频繁变化时,低阶方法可能允许更大的可靠步长。
7.4 Adams 的稳定性步长上限约束
上面的
设从校正迭代得到的局部 Jacobian/Lipschitz 尺度估计为
因此实际允许的倍率是
如果第二项更小,就说明 Adams 的步长不是由误差容限决定,而是被稳定性或函数迭代收敛性限制。后面我们会看到,这正是“当前区域表现出刚性”的可计算信号。
你可能会好奇 BDF 为什么没有相应的约束,其实 BDF 也有相应的稳定性问题,但是相比于 Adams,BDF 的稳定性要求宽泛很多,这就涉及到了两者的稳定性分析。分析的具体内容我计划另写一篇文章,敬请期待!
7.5 迟滞与失败恢复
误差和高阶导数估计本身带有噪声。如果每一步都改变
- 建议步长增加不足约
时,通常保持原步长; - 改变步长后,延迟若干步再考虑变阶;
- 失败后限制下一次允许的放大倍率;
- 连续误差失败时更激进地缩短步长;
- 多次失败后降到一阶并重新计算导数历史。
8. 从稳定性受限到自动切换方法
LSODA自动切换方法的原则是:
如果 Adams 因稳定性只能使用远小于精度所允许的步长,并且 BDF 预计能以足够大的步长优势抵消矩阵运算成本,那么当前区域值得切换到 BDF。
为此,我们需要估计 Adams 方法的稳定性限制,以及两种方法的估计步长。
8.1 从函数迭代收敛率估计局部动力学尺度
Adams 函数迭代在线性化后满足
记连续校正增量的加权范数为
则比值
包含了
从7.4小节我们知道,Adams 步长的选取收到稳定性的限制,于是我们可以据此来判断 Adams 的候选步长是否会被稳定性压制。这点是十分重要的,因为在比较两者的步长时,Adams的估计步长需要考虑稳定性的影响(下面我们还会再特意强调这一点)。
这一估计几乎是免费的,因为校正迭代本来就需要计算
8.2 两种方法怎样在同一尺度上比较
定义共同的局部高阶导数尺度
所谓的“共同”,指的是不论对于 Adams 方法还是 BDF 方法,其误差表达式中都含有这样的因子。
我们可以利用当前方法的校正量给出它的估计:
再将其分别代入两种方法的误差主项,就得到
于是,两种方法在同一误差权重下的无量纲局部误差为
实际上,我们可以直接利用
来估计另一方的误差。
得到误差估计后,利用
可分别得到两种方法由精度允许的候选步长倍率
其中
需要注意的是,这里的
如果两种候选方法的阶数不同,便不能只使用
再乘以各自的误差常数。从这里我们也可以看出 Nordsieck 向量表示的优越性。
8.3 切换判据的不对称性
Adams 每步通常只需要少量右端函数计算;BDF 还需要 Jacobian、矩阵分解和线性系统求解。所以同样的步长并不意味着同样的成本。所以并不意味着只要 BDF 的步长比 Adams 的大,我们就进行方法切换。
实际上,LSODA 默认使用如下迟滞策略:
Adams 到 BDF
只有当
时才切换。BDF 必须表现出显著的步长优势,才值得支付刚性分支的额外成本。若当前 Adams 阶数高于 BDF 的最高阶 5,则不做常规切换比较。另外,如果误差或收敛率已经接近舍入噪声,普通倍率估计可能失真。此时只有在 Adams 步长已经明确被稳定性上限截断时,才把它作为切换证据。
BDF 到 Adams
反方向的默认条件近似为
因为 Adams 单步更便宜,只要它能够采用不小于 BDF 的步长,就可能值得切回。同样的,切换前仍需确认误差估计没有被舍入噪声淹没,并检查 Adams 的稳定性上限。
除此之外,LSODA的方法切换存在一个“保护期”。由于方法切换会改变:
- 校正多项式
; - 误差常数;
- 最高允许阶数;
- 非线性迭代方式;
- 是否需要 Jacobian 和矩阵工作区。
切换后立即根据尚未稳定的新历史再次判断,容易产生 Adams/BDF 来回抖动。所以LSODA 在初始化和每次切换后设置约 20 个成功步的保护计数,先积累可靠的历史数据,再重新比较两种方法。
到这里,DLSODA 的核心算法已经从基本原理构造完成。下一篇文章我们会关注程序上的实现(希望会有下一篇文章吧),因为我们知道将算法原理转化为程序实现,并不是一个简单的映射,其中还有非常多的小巧思。






