
NumPy 的 numpy.roots() 并不依赖解析公式(因五次以上无通用根式解),而是将多项式求根问题转化为 companion 矩阵的特征值计算问题,再通过成熟的数值线性代数算法(如 QR 迭代)高效、稳定地求解。
numpy 的 `numpy.roots()` 并不依赖解析公式(因五次以上无通用根式解),而是将多项式求根问题转化为** companion 矩阵的特征值计算问题**,再通过成熟的数值线性代数算法(如 qr 迭代)高效、稳定地求解。
numpy.roots() 的核心思想是:任何一元 n 次多项式均可等价转化为一个 n×n 友矩阵(companion matrix)的特征值问题。该友矩阵的特征多项式恰好等于原多项式,因此其特征值即为原多项式的全部复数根(含重根与共轭对)。
例如,对五次多项式
$$
p(x) = x^5 - 7x^4 + 15x^3 - 5x^2 - 16x + 12
$$
其标准友矩阵(首一多项式、降幂排列)定义为:
$$ C = \begin{bmatrix} 0 & 0 & 0 & 0 & -12 \ 1 & 0 & 0 & 0 & 16 \ 0 & 1 & 0 & 0 & 5 \ 0 & 0 & 1 & 0 & -15 \ 0 & 0 & 0 & 1 & 7 \ \end{bmatrix} $$
注意:NumPy 实际采用的是“上移型”友矩阵(第一行为系数的负值,其余为移位单位元),对应 np.roots([1,-7,15,-5,-16,12]) 的输入顺序(从最高次到常数项)。
import numpy as np
# 系数按降幂排列:x^5 -7x^4 +15x^3 -5x^2 -16x +12
coeffs = [1, -7, 15, -5, -16, 12]
roots_np = np.roots(coeffs)
print("NumPy roots:", np.round(roots_np, 8))
# 输出接近 [-1., 1., 2., 2., 3.](含重根)关键在于:特征值计算本身不依赖求解高次方程。NumPy(底层调用 LAPACK)使用高度优化的 QR 迭代算法(带位移的隐式 QR)来计算矩阵特征值。该算法通过反复进行正交相似变换($A_{k+1} = R_k Q_k$,其中 $A_k = Q_k R_k$),使矩阵逐步收敛至拟上三角(Schur 形式),对角块直接给出实特征值或共轭复特征值对。
⚠️ 注意事项:
-
roots()返回的是浮点近似解,受舍入误差影响,重根可能表现为极接近的数值(如1.99999992和2.00000008),需结合容差判断(如np.isclose()); - 对病态多项式(如 Wilkinson 多项式),即使系数微小扰动也会导致根剧烈偏移,此时建议改用符号计算(如 SymPy)或更高精度库;
- 该方法时间复杂度为 $O(n^3)$,适用于中等规模($n \lesssim 1000$);超大规模建议考虑稀疏结构或专用根求解器。
总结:numpy.roots() 是“代数问题线性化”的典范实践——它绕开了阿贝尔–鲁菲尼定理的理论限制,将不可解的解析难题,转化为成熟、鲁棒、可扩展的数值线性代数问题,体现了科学计算中“转化思维”的强大威力。

















