跳到正文
格致开物MATHWIKI

延拓法

延拓法(continuation method)从一个已知解出发,逐渐改变参数并追踪方程的解分支。它常用于非线性方程、平衡态和分岔计算。预测步根据已有分支方向提出新初值,校正步再把该初值投回方程的解集;这比每个参数点都独立盲选初值更能利用相邻解之间的关系。

参数改变时追踪同一条解支

考虑 F(x,λ)=x2−λ=0。已知 (x,λ)=(1,1),若用 λ 作参数,正支为 x=λ,导数满足 Fxdxdλ+Fλ=0,dxdλ=12x. 在远离零的地方,这个导数可预测下一个初值,再用 Newton 法解新的 x2−λ=0。但到 x=0 时导数发散;真实解曲线 λ=x2 仍光滑,只是不能继续把 λ 当成局部单值的自变量。这个转折称为折叠点。

抛物线解支在原点转折,沿弧长方向可从正x支穿过原点进入负x支
横轴为x,纵轴为参数λ。参数λ在折点先减后增;伪弧长法追踪的是曲线方向,允许这种参数回转。

切向预测与伪弧长约束

对 F(x,λ)=0,其中 x∈ℝn、F∈ℝn,解曲线切向量 t=(tx,tλ) 满足 Fxtx+Fλtλ=0,‖t‖2=1. 切向符号通过与上一轮方向内积为正来保持。给定步长 Δs,先作预测 zp=zk+Δstk,其中 z=(x,λ);再解增广方程 F(x,λ)=0,tkT(z−zp)=0. 第二式要求校正点位于穿过预测点、垂直于旧切向的超平面。这叫伪弧长约束,实际新旧点的曲线弧长未必恰等于 Δs,因此不应把它称为精确弧长积分。AUTO 的官方手册使用伪弧长延拓,并以 DS 控制初始步长、以 DSMIN 和 DSMAX 限制自适应步长范围;一次校正失败时,程序可减半步长后重试。[1]

跨过折点的非奇异性

本例切向满足 tλ=2xtx。取向左追踪的单位切向 t=(−1,−2x)/1+4x2。校正 Newton 系统的 Jacobian 为 Jaug=(2x−1txtλ). 若在当前曲线上评价并使用相应切向,其行列式为 2xtλ+tx=(1+4x2)tx=−1+4x2≠0. 特别在折点 x=0,原来的 Fx=0,增广矩阵却为 (0−1−10),仍可逆。隐函数定理于是保证附近的增广校正局部有唯一解。这个证明解释伪弧长法能跨越简单折叠;若整个 [Fx Fλ] 失去行满秩,解集可能出现真正分岔,增加这一条约束未必足够。

两个可手算的预测—校正步骤

从 (1,1) 出发,取 t=(−1,−2)/5、Δs=5/4,预测点为 (3/4,1/2)。校正超平面为 x+2λ=7/4. 与 λ=x2 联立得到 2x2+x−7/4=0。选择靠近预测点的根,得到 x=−1+154≈0.718245837,λ=1−158≈0.515877082. 方程另有远处负根,所以“局部唯一”不能误读成这个超平面在全局只与曲线交一次。步长和校正初值决定继续哪一段解支。

有解变式直接从折点 (0,0) 出发,切向取 (−1,0),步长为 0.2。预测点为 (−0.2,0),约束固定 x=−0.2,代入原方程得 λ=0.04。参数自动回升,算法已进入负支;如果坚持让 λ 一直下降,就无法描述这条实际曲线。

一个可运行的增广 Newton 校正器

代码针对本例,从给定曲线点计算向左切向、作预测并校正。它返回新点,不修改输入;迭代残差同时检查原方程和伪弧长约束。每轮只解二阶系统,为常数成本;一般大系统的主要成本在增广线性求解和 Jacobian 构造。

Python 3
import math


def fold_continuation_step(x0, lam0, ds, tol=1e-12, maxiter=30):
    x0, lam0, ds, tol = map(float, (x0, lam0, ds, tol))
    if not all(math.isfinite(v) for v in (x0, lam0, ds, tol)) or ds <= 0 or tol <= 0:
        raise ValueError("finite data and positive step/tolerance required")
    if abs(x0*x0-lam0) > tol*max(1.0, abs(lam0)):
        raise ValueError("starting point must satisfy the branch equation")
    if not isinstance(maxiter, int) or maxiter <= 0:
        raise ValueError("positive integer maxiter required")
    length = math.hypot(1, 2*x0); tx, tl = -1/length, -2*x0/length
    xp, lp = x0+ds*tx, lam0+ds*tl; x, lam = xp, lp
    for _ in range(maxiter):
        g1, g2 = x*x-lam, tx*(x-xp)+tl*(lam-lp)
        if not all(math.isfinite(v) for v in (x, lam, g1, g2)):
            raise ArithmeticError("nonfinite corrector")
        if math.hypot(g1, g2) <= tol:
            return x, lam
        determinant = 2*x*tl+tx
        if determinant == 0 or not math.isfinite(determinant):
            raise ArithmeticError("singular augmented corrector")
        dx = (-tl*g1-g2)/determinant
        dl = (tx*g1-2*x*g2)/determinant
        x += dx; lam += dl
    raise RuntimeError("corrector failed to converge; reduce continuation step")


print(fold_continuation_step(1, 1, math.sqrt(5)/4))
# (0.7182458366..., 0.5158770817...)
print(fold_continuation_step(0, 0, 0.2))  # (-0.2, 0.04)

自适应步长可根据校正次数、曲率变化和误差估计调整。延拓并不保证找到全部解支,遇到分岔还需检测、分支切换和稳定性分析。将一个容易问题连续变为目标问题的同伦法属于相关思路,但参数构造与是否追踪所有分支仍须具体说明。

参考资料

  1. ↑ AUTO-07p authors. AUTO-07p 官方手册 LaTeX 源文件,Continuation Step Size 节的 DS、DSMIN、DSMAX、IADS。