刚性检测
概述
许多微分方程表现出某些形式的刚性,从而限制步长大小,进而限制了显式求解方法的有效性.
对于同样的步长,由于与内在的线性代数相关的开销,隐式方法的效率可能会显著低于显式方法.
由于在某些区域,隐式方法可以使用显著增加的步长,该成本可以被抵消.
我们作了多次尝试来提供用户友好的代码,以便自动尝试在运行时检测刚性,并在必要时在适当的方法之间转换.
这里对一些已经提出的自动为代码配备刚性检测设备的策略作一概述.
特别关注的是一个矩阵的主导特征值的估计问题,以描述刚性检测如何在
NDSolve 里实现.
初始化
引言
刚性是问题、解法、初始条件和局部误差容差的一个结合体.
由于对可以采取的步长的限制,刚性限制了显式解法的有效性.
刚性出现在许多实际系统中,以及在由直线法求解的偏微分方程的数值解中.
示例
范德波尔振荡器是一个非保守的非线性阻尼振荡器,它是一个常微分方程:
的刚性系统的例子. 其中

;
并且在区间

上求解.
方法

默认时使用一对插值方法:
- 显式修改中点(Explicit modified midpoint,即 Gragg 平滑),双谐波序列 2,4,6 ...
解
下面是两个解组成部分的图形. 尖峰(蓝色)在幅度上扩大至大约450,并且已经被裁剪.
| Out[13]= |  |
| Out[14]= |  |
问题是,当解快速变化时,几乎没有用刚性求解器的必要,因为局部准确性是主要问题.
为了提高效率,如果该方法能够自动检测出那些局部准备性(而不是稳定性)更为重要的区域,那将是很有用的.
线性稳定性
线性稳定性理论源于 Dahlquist 标量线性测试方程:
的研究,作为研究初值问题 (
1) 的一个简化模型.
稳定性是通过分析应用到 (
2) 以得到下式的方法来描述的:
这里

,

是(有理)稳定性函数.
显式欧拉法
阴影区域代表不稳定性,其中

.
| Out[15]= |  |
对于显式欧拉方法,线性稳定性边界

.
对于一个特征值
,线性稳定性的要求表示步长需要满足 
,这是一个非常温和的限制.
然而,对于一个特征值

,线性稳定性的要求表示步长需要满足

,这是一个非常严格的限制.
示例
这个例子表明当使用显式 Runge-Kutta 方法求解一个刚性系统时,刚性对步长序列的影响.
| Out[18]= |  |
- 大量的步拒绝(step rejections)常常会对性能产生负面影响.
隐式欧拉法
| Out[20]= |  |
类型不敏感(Type Insensitivity)
一个对类型不敏感的求解器在每个步骤对刚性进行确认并有效地作出反应,因此对于问题的类型(有可能是变化的)是不敏感的.
这种类型的求解器中最完善的之一是 LSODA [
H83], [
P83].
LSODA 的后代求解器如 CVODE 不再纳入刚性检测设备. 原因是 LSODA 使用范数界限来估计主导特征值,而这些界限可以是相当不准确的,这一点将在后面的讨论中看到.
低阶的A(

)-稳定的 BDF 方法意味着 LSODA 和 CVODE 不适合求解具有高准确度的,或者主导特征值具有大的虚部的系统. 其他的方法,如那些基于线性隐式的方案的外推法就不会有这些问题.
关于刚性检测的大部分工作是在80年代和90年代使用独立的 FORTRAN 代码实现的.
此后,出现了新的线性代数技术和有效的软件,这些都可在
Mathematica 中获得.
刚性可以是一个短暂的现象,因此检测非刚性是同样重要的 [
S77], [
B90].
"StiffnessTest" 方法选项
有好几种方法可用于从非刚性求解器到刚性求解器的转变.
直接估计
检测刚性的一个方便的方法就是直接估计该问题的雅克比

的主导特征值(见 [
S77], [
P83], [
S83], [
S84a], [
S84c], [
R87] 和 [
HW96]).
这一个估计往往可以作为数值积分的副产品加以利用,所以代价合理地低.
如果

代表对应于雅可比的主导特征值的特征向量的一个近似,同时

足够小,那么根据中值定理,主导特征值的一个很好的近似是:
Richardson 外推法提供了产生这种形式的量的一个优化序列,如某些显式 Runge-Kutta方法一样
成本最多是两个函数计算,但是往往其中至少有一个是数值积分的副产品,因此它的代价合理地低.
用

表示线性稳定性边界——它是线性稳定性区域和负实轴的交集.
积

给出一个可以和一个方法的线性稳定性边界相比较的估计,以便检测刚性:
其中

是一个安全因子.
描述
方法

、

和

具有选项

,它可以用来识别该方法在应用指定的
AccuracyGoal 和
PrecisionGoal 容差时对于一个给定的问题是否是刚性的.
方法选项

本身接受许多选项来执行 (
5) 的一个弱形,允许测试失败指定数目的次数.
这样做的原因是有些问题只在某些区域有轻度的刚性,而一个显式积分方法可能仍然是有效的.
"NonstiffTest" 方法选项

方法具有选项

,它用来把一个刚性方法转变回一个非刚性方法.
对于选项

允许下列设置:
转化到一个非刚性求解器
范数界限(Norm Bound):

谱半径:

主导特征值

.
对于刚性检测,具有精确到一或二位数字的解的一系列问题就足够了.
考虑在某(一些)子区间上的一系列

个矩阵
我们的目标是找到一种估算矩阵系列

的主导特征值(的边界),以满足:
- 在刚性求解器中的每一步,成本低于在线性代数中实施的工作.
NormBound
获取主导特征值的界限的一个简单有效的技术是使用雅可比的范数

, 通常

或者

.
该方法具有复杂度

,它少于在刚性求解器中采取的工作.
- 稠密矩阵的范数界限高估了,而在维度增加时,界限变得更不理想.
- 范数界限对于具有相当大维度的稀疏矩阵或者带状矩阵可能是很紧张的.
选项

的设置

计算

和

并且返回这两个值中较小的一个.
示例
下面雅可比矩阵出现在使用刚性求解器的 van der Pol 系统的数值解中.
| Out[22]= |  |
直接特征值计算
对于小型问题 (

) 直接计算主导特征值可能更有效.
- 厄米 (Hermitian) 矩阵采用 LAPACK 函数 xgeev
幂法
Shampine 提出了采用幂法来估计雅可比的主导特征值 [
S91].
幂法也许不是一个很备受尊重的方法,但是由于它在 Google 页面排名中的使用,很多人已经重新对其表示兴趣.
具有
个线性独立的特征向量(可对角化的).
- 特征值可以按大小排序,如
.
是
的主导特征值.
描述
给定一个初始向量

,计算
属性
特别是,当应用于具有复共轭的主导特征值对时,该方法不收敛.
推广
幂法可以通过适应性修正来克服等模(equimodular)特征值问题(如 NAPACK).
但是,这样的修正一般不处理集群特征值的收敛速度慢的问题.
子空间迭代
子空间(或同时)迭代通过每一步作用于

个向量推广了幂法中的思想.
从一个正交向量集

开始,通常

:
形成与矩阵

的积:
为了防止所有向量收敛到

的同一主导特征向量

的倍数,它们被正交归一化:
Rayleigh-Ritz 投影
输入:矩阵

和向量

的一个标准正交集合
- 计算 Rayleigh 商

- 计算 Schur 分解

请注意,当

时,使用一个准上三角矩阵

,Schur 分解可以实数运算来计算.
收敛性
子空间(或者同时)迭代通过在每一步作用于

个向量,推广了幂法中的思想.
因此,采用比如

或者更多是有益的,即使我们只对主导特征值感兴趣.
误差控制
这是不够的,因为当收敛速度很慢时,它仍可以被满足.
这是有利的,因为它适用于等模(equimodular)特征值.
因为有序 Schur 分解的使用,要对上三角矩阵

的第一列的位置进行测试.
实施
- 采用切比雪夫(Chebyshev) 加速的子空间迭代 [S84b], [DS93]
在

中所用的实现方法是以:
- Schur Rayleigh-Ritz 迭代 [BS97]
"SRRIT 的一个吸引人的特点是它显示了单调一致性,即当收敛容差减小时,计算得的残差的大小也减小" [
LS96].
SRRIT 用到了有序 Schur 分解,其中具有最大模的特征值出现在左上角的项中.

的形成用到了重新正交归一化的修正的 Gram-Schmidt,这比Householder变换速度更快.
在积分时间

的近似主导子空间

用于启动在下一个积分步骤

时的迭代:
KrylovIteration
给定一个



矩阵

,其列

组成了一个给定子空间

的正交基:
Rayleigh Ritz 程序包含计算

以及求解相关的特征值问题

.
原问题的近似特征对

,

满足

和

,它们被称为 Ritz 值和 Ritz 向量.
当子空间

接近

的不变子空间时,该过程效果最佳.
当

等于与矩阵

和给定初始向量

相关的 Krylov 子空间时,这个过程有效:
描述
Arnoldi 方法是一种基于 Krylov 的投影算法,它计算 Krylov 子空间的一个正交基,并且产生一个投影的



矩阵

其中

.
输出:

其中

在 Arnoldi 的情况下,

具有一个未约化(unreduced)的上黑森贝格形式( upper Hessenberg form),即具有一个额外的非零次对角的上三角.
正交化通常是通过格拉姆-施密特程序的方法来完成的.
残差

给出了一个对不变子空间的近似的指示,相关的范式

表明了计算 Ritz 对的精度:
重启
如果初始向量

在预期特征值的方向是丰富的话,Ritz 对的收敛速度很快的.
当情况并非如此时,则需要一个重新启动的策略,以避免工作量和内存的过快增长.
- 显式重启 —— 一个新的启动向量是 Ritz 向量的子集的线性组合.
实现
在

中的实现是基于Krylov-Schur 迭代的.
Automatic 策略

设置使用这些方法的一个组合,情形如下.
- 对于
采用直接特征值计算. 或者使用
或者
,取决于哪种方法是主动(active)的.
- 对于
采用子空间迭代,默认的基的大小为
. 如果该方法成功,那么得到的基用来在下个积分步骤启动该方法.
- 如果子空间迭代在
个迭代后没有收敛,那么主导向量将被用来启动默认基大小为
的 Krylov 方法. 接下来的积分步骤使用 Krylov 方法,从上一步得到的向量开始.
- 如果 Krylov 迭代在
个迭代后没有收敛,那么范数界限将被用于当前步骤. 下一个积分步骤将继续尝试 Krylov 迭代.
- 由于它们的代价如此低,当使用子空间或者 Krylov 迭代时,以及绝对值中较小的被使用时,范数界限总是被计算.
步骤拒绝
对计算时间的缓存确保了主导特征值估计不在被拒绝的步骤重新计算.
- 当在稳定性边界工作时,对于非刚性求解器常常出现步骤拒绝.
迭代方法选项

的迭代方法具有可被修改的选项:
| Out[23]= |  |
| Out[24]= |  |
默认容差的目的是只有一个正确数位,但往往得到更准确的值——特别是在连续的步骤中几个成功的迭代之后.
- 对于子空间迭代
.
延迟和切换
有一点很重要,就是将某种形式的延迟结合进来,以避免一种

方法不断尝试在刚性和非刚性方法之间切换的循环.
默认设置允许切换是相当被动的,这对于单步积分方法是恰当的.
- 对于非刚性方法,
是在每个步的结尾执行的. 当选项
的任何值达到时,出现一个步骤拒绝,然后用一个刚性方法重新计算该步骤.
是抢先执行的. 它是在一个刚性方法采取一个步骤之前, 用上一步的雅可比矩阵来实施的.
示例
Van der Pol
StiffnessTest
该系统用一个给定的方法和

的默认选项设置被成功地积分.
| Out[26]= |  |
当刚性测试条件不满足时,一个较长的积分将中止,并发出提示信息.
| Out[27]= |  |
使用单位安全系数,并指定只允许有一个刚性失败,这样做实际上给出了一个严格的测试. 该项指定使用了嵌套的方法选择句法.
| Out[28]= |  |
NonstiffTest
这个例子是一个很好的测试,体现了整体刚性切换架构的行为正如预期.
建立一个函数来监控刚性方法和非刚性方法之间的转换以及所采用的步长. 刚性方法和非刚性方法的数据通过使用
Sow 的一个不同标签放置在了不同的列表中.
画出使用显式求解器(蓝色)和隐式求解器(红色)所采用的步长的图形.
| Out[33]= |  |
| Out[34]= |  |
CUSP
关于神经冲动机制的 cusp catastrophe 模型 [
Z72]:
与 van der Pol 振荡器相结合产生了 CUSP 系统 [
HW96]:
而

并且

.
利用直线法对扩散项进行离散化从而得到一个维度为

的常微分方程组.
与 van der Pol 系统不同,因为问题的大小,我们采用迭代方法来进行特征值估计.
步长和阶数选择
建立一个函数来监控使用的方法类型和步长. 另外,方法的阶数作为一个工具提示条被包含在内.
画出使用显式求解器(蓝色)和隐式求解器(红色)所采用的步长. 一个工具提示条显示了在每步的方法阶数.
| Out[40]= |  |
| Out[41]= |  |
雅可比实例
一个到刚性方法的转换出现在

附近,而非刚性的第一个测试出现在下一步

.
雅可比

的图形展示.
| Out[46]= |  |
定义一个函数来计算并且显示

,

, ... 等等的前几个特征值,以及范数界限.
| Out[47]= |  |
Korteweg-deVries
Korteweg-deVries 偏微分方程是在浅水表面的波浪的数学模型:
并且在区间

上求解.
采用直线法的离散化用来形成由 192 个常微分方程组成的方程组.
步长
在 LSODA 中使用的向后差分公式方法在求解这一问题时遇到了困难.
| Out[50]= |  |
| Out[51]= |  |
相反,

立即切换到使用线性隐式欧拉方法,它需要很少的积分步骤.
| Out[52]= |  |
| Out[53]= |  |
一旦在积分开始的时候选择了刚性方法,插值法从来不会切换回非刚性求解器.
尽管如此,使用子空间迭代的成本仅是总积分时间的百分之几.
| Out[54]= |  |
雅可比实例
采用前面定义的监控函数,收集前几个雅可比矩阵的数据.
初始雅可比

的图形显示.
| Out[57]= |  |
计算并且显示

,

, ... 的前几个特征值,以及范数界限.
| Out[57]= |  |
范数界限略被高估,但更重要的是,他们没有提供实部和虚部的相对大小的显示:
选项总结
StiffnessTest
| | |
| "MaxRepetitions" | {3,5} | 指定刚性测试 (6) 允许的连续失败的最大次数和失败的总次数的最大值 |
| "SafetyFactor" |  | 指定在刚性测试 (7) 的右侧所使用的安全系数 |
方法选项
的选项.
NonstiffTest
| | |
| "MaxRepetitions" | {2,∞} | 指定刚性测试 (8) 允许的连续失败的最大次数和失败的总次数的最大值 |
| "SafetyFactor" |  | 指定在刚性测试(9)的右侧所使用的安全系数 |
方法选项
的选项.