应优先使用 numpy.linalg.eigh 求实对称矩阵特征值,因其返回实数、正交特征向量且更稳定;若用 eig,结果含微小虚部属正常现象,可取实部并验证虚部是否接近零。

用 numpy.linalg.eig 求实对称矩阵的特征值,但结果可能含虚部?
即使输入是实对称矩阵,numpy.linalg.eig 默认返回复数类型数组——因为它的通用实现不假设对称性,内部调用的是通用非对称求解器。你看到的 array([1.0+0.j, 2.0+0.j]) 是正常现象,不是错误。
实操建议:
- 若确认矩阵对称(或厄米),优先改用
numpy.linalg.eigh:它专为对称/厄米矩阵设计,返回实数特征值,数值更稳定,速度也更快 - 若必须用
eig,可手动取实部:np.real(eigvals),但需先验证虚部是否全接近零(如np.allclose(np.imag(eigvals), 0)) - 注意:
eigh对输入不做对称性检查,传入非对称矩阵会导致结果无意义
numpy.linalg.eig 返回的特征向量为什么“看起来不正交”?
对非对称矩阵,特征向量本就不保证正交;即使对实对称矩阵,eig 也不强制正交化,而 eigh 返回的特征向量是标准正交的(列向量满足 V.T @ V == I)。
常见错误现象:用 eig 算对称矩阵后,发现 V.T @ V 不是单位阵,误以为计算出错。
使用场景判断:
- 需要正交特征向量 → 必须用
eigh,且输入确保对称(可用A = (A + A.T) / 2强制对称) - 处理一般方阵(如转移矩阵、雅可比矩阵)→ 用
eig,接受非正交结果 - 验证正交性时,别直接用
==比较浮点矩阵,改用np.allclose(V.T @ V, np.eye(n))
大规模稀疏矩阵用 numpy.linalg.eig 崩溃或极慢?
numpy.linalg 全部基于密集矩阵算法,时间复杂度 O(n³),内存占用 O(n²)。对 n > 5000 的矩阵,基本不可行;若矩阵实际稀疏(如邻接矩阵),硬转成 ndarray 会吃光内存。
性能与兼容性影响:
- 替代方案:用
scipy.sparse.linalg.eigs(求部分特征值)或scipy.sparse.linalg.eigsh(对称/厄米稀疏矩阵) - 注意接口差异:
eigs默认只返回前 6 个模最大的特征值,需显式指定k=和which=(如which='LM'或'SM') - 输入必须是
scipy.sparse格式(如csr_matrix),不能直接喂 NumPy 数组
特征值排序和重根处理:NumPy 不自动排序,也不合并重复值
eig 和 eigh 返回的特征值默认按算法内部顺序排列,不按大小、不按实部、不按模长——尤其 eigh 虽保证实数输出,但顺序仍取决于底层 LAPACK 实现。
容易踩的坑:
- 想取最大特征值?别假设索引
[0]就是最大,务必手动排序:idx = np.argsort(eigvals)[::-1]再索引 - 重根(代数重数 > 1)时,对应特征向量可能线性相关但数值上不完全一致,
eig不做正则化或正交补全;若需标准正交基,得自己用np.linalg.qr对子空间正交化 - 对称矩阵理论上有完备正交特征向量系,但有限精度下,小扰动可能导致数值秩亏损,此时
eigh仍返回 n 个向量,但最后几个可能精度极低
np.float64 已是默认,float128 支持有限)。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











