科列斯基分解
科列斯基分解(Cholesky decomposition,也译乔列斯基分解)把实对称正定矩阵写成 ,其中 是对角元严格为正的下三角矩阵。复数情形将对称换为厄米、转置换为共轭转置。它把一个正定线性方程组拆成两次三角求解,也给出二次型是平方和的表示。[1]
考虑教学矩阵 要找下三角 ,不需要猜九个元素;上三角的三个位置已经固定为零,剩下六个数可按列依次确定。
从矩阵乘积读出递推式
写 ,约定 当 。乘积的第 项为 第 列之前的列已知时,对角等式决定 选择正平方根;该列下面的元素则由 确定。分子减去前面各列已贡献的部分,余下的乘积只有 ,因此这一步可以除以已经得到的正对角元。
原例第一列是 、。第二列先取 ,再取 。最后 ,所以 核验非对角元时,第二行与第三行的内积为 ,恰与 相同;不能把负的非对角元误当成非正定的证据。
正定性保证递推不会中断
定理 每个实对称正定矩阵都有唯一的、对角元为正的科列斯基分解。
先证明存在。对阶数归纳,一阶情形为正数开平方。高阶时把矩阵分块为 第一列必须为 。扣掉它对右下块的贡献,剩下 。对任意非零向量 ,取 ,直接展开得到 故 仍正定。按归纳假设 ,于是 满足 。这也说明每一步的剩余对角量都严格为正。至于唯一性,第一列由 和正平方根唯一确定,剩余分解又由同一归纳过程唯一确定,故全部列唯一。
反向若 且 的对角元非零,则对非零 ,,因此 。这证明了分解条件与正定性的对应,而不只是递推公式恰好能运行。
三角求解与平方和
求 时先解 ,再解 。原例取 ,前代依次得到 、、。回代得到 、、。代回原式即为 。
同一分解还给出 三个平方同时为零时,先由最后一项得到 ,再依次得到 ,与正定性吻合。
作为变式,把 从三改为二,最后一个对角量成为零。新矩阵只有半正定,递推的正对角约定不再适用;向量 使上述前两个平方均为零,新二次型等于零。半正定情形可以有零对角因子,但须另行处理零主元,不能在下一步继续除以零。
可运行的实数实现
下面接受有限实数构成的方阵,要求转换为浮点数后严格对称,返回新的下三角列表,不改写输入;发现非正主元就报错。空矩阵返回空列表。它对应上面的数学递推,未实现针对病态数据的误差认证。
from math import isfinite, sqrt
def cholesky(source):
a = [list(map(float, row)) for row in source]
n = len(a)
if any(len(row) != n for row in a):
raise ValueError("matrix must be square")
if any(not isfinite(x) for row in a for x in row):
raise ValueError("entries must be finite")
if any(a[i][j] != a[j][i] for i in range(n) for j in range(i)):
raise ValueError("matrix must be symmetric")
lower = [[0.0] * n for _ in range(n)]
for j in range(n):
pivot = a[j][j] - sum(lower[j][k] ** 2 for k in range(j))
if pivot <= 0:
raise ValueError("nonpositive pivot")
lower[j][j] = sqrt(pivot)
for i in range(j + 1, n):
residual = a[i][j] - sum(lower[i][k] * lower[j][k]
for k in range(j))
lower[i][j] = residual / lower[j][j]
return lower
a = [[4, 2, 2], [2, 5, -1], [2, -1, 3]]
assert cholesky(a) == [[2.0, 0.0, 0.0], [1.0, 2.0, 0.0], [1.0, -1.0, 1.0]]
assert cholesky([]) == []
for bad in ([[1, 1], [1, 1]], [[1, 2], [2, 1]], [[1, 0], [1, 1]]):
try:
cholesky(bad)
except ValueError:
pass
else:
raise AssertionError("invalid input accepted")
print("all checks passed")
每轮正确得到第 列,因为所有求和只使用已经确定的列;存在性证明保证精确算术下的正定输入不会遇到非正主元。三重求和总计 时间,输出与副本需 空间;分解完成后,每次三角求解为 。浮点消去可能使很小的正主元被舍入为非正,因此程序报错不是关于原始精确数据的独立正定性证明;实际库会结合误差分析与数据尺度使用该算法。[1]
参考文献
- ↑ 1.0 1.1 Nicholas J. Higham,What Is a Cholesky Factorization?,2020年8月11日。