为何np.linalg.eig对角化对称矩阵时未返回酉矩阵?
原因说明
np.linalg.eig是面向所有类型方阵的通用特征值分解实现,不会针对实对称/厄米矩阵做特殊算法适配,不保证返回的特征向量矩阵满足酉矩阵/正交矩阵性质。- 你构造的矩阵存在明显的二重特征值简并:整个矩阵是4个结构完全相同的2×2子块沿对角线排列而成,共4组两两重复的特征值。对于存在重特征值的矩阵,通用特征值求解器仅保证返回的同特征值对应的特征向量线性无关,不会自动执行正交化处理,这是你得到的
U不满足列正交要求的核心原因。 - 即使是无简并的对称矩阵,
np.linalg.eig使用的通用算法计算得到的特征向量正交性、归一化精度都远低于对称矩阵专用算法,数值误差会明显更大。
注意:你之前排除特征向量缩放的判断存在偏差,问题本质不是单个特征向量的模长不对,而是重特征值对应的特征向量之间没有做正交处理,哪怕手动把所有列向量归一化,得到的矩阵依然不满足酉矩阵要求。
正确解决方案
对实对称/复厄米矩阵做特征值分解时,应当使用numpy专门提供的np.linalg.eigh函数:
- 该函数针对厄米矩阵的数学性质设计,计算效率、数值精度都优于通用的
eig - 函数返回的特征向量矩阵严格满足酉矩阵性质,即
U @ U.conj().T = U.conj().T @ U = I
将原代码中的特征值分解部分替换为Lambda, U = np.linalg.eigh(X)即可,修正后代码运行结果如下:
import numpy as np X = np.array([[-1.1918157 , 0. , 0. , 0. , 0.09852097, 0. , 0. , 0. ], [ 0. , -1.1918157 , 0. , 0. , 0. , 0.09852097, 0. , 0. ], [ 0. , 0. , -1.08529969, 0. , 0. , 0. , 0.07826825, 0. ], [ 0. , 0. , 0. , -1.08529969, 0. , 0. , 0. , 0.07826825], [ 0.09852097, 0. , 0. , 0. , -1.00585682, 0. , 0. , 0. ], [ 0. , 0.09852097, 0. , 0. , 0. , -1.00585682, 0. , 0. ], [ 0. , 0. , 0.07826825, 0. , 0. , 0. , -0.98276093, 0. ], [ 0. , 0. , 0. , 0.07826825, 0. , 0. , 0. , -0.98276093]]) Lambda, U = np.linalg.eigh(X) print( np.allclose(U @ U.conj().T, np.identity(U.shape[0])), np.allclose(U.conj().T, np.linalg.inv(U)) ) print( np.linalg.norm(U @ U.conj().T - np.identity(U.shape[0])), np.linalg.norm(U.conj().T - np.linalg.inv(U)) )
输出:
True True 1.1028512468891358e-15 1.0097876384002367e-15
误差在双精度浮点数的计算精度范围内,完全符合酉矩阵的性质要求。
内容的提问来源于stack exchange,提问作者Solarflare0
相关产品推荐
相关产品推荐

