numpy Polynomial.roots()返回虚假根的原因及解决方法咨询
问题原因
这个问题核心是多项式系数病态导致的浮点计算误差,你提供的三次多项式系数动态范围超过16个数量级(常数项≈4,最高次项系数≈-4e16),numpy的Polynomial.roots()底层采用伴随矩阵特征值求解的方法,对这类系数量级差异过大的病态多项式稳定性极差,会产生完全不符合实际的虚假根,你得到的-1.6e9量级的根就是典型的浮点计算赝像。
可行规避方案
- 方案1:多项式归一化缩放
对系数做归一化处理,或者通过变量代换将根的预期量级压缩到1附近,大幅降低系数动态范围,再执行求根操作,可显著提升计算稳定性。 - 方案2:改用区间迭代求根算法
放弃伴随矩阵类的全局求根方法,改用scipy的root_scalar等工具,先通过多项式求值锁定有效根的大致区间,再用二分法、牛顿法等迭代方法求解,这类方法对病态多项式的适应性远好于全局求根。示例参考:
上述方法得到的根代入多项式的误差会远小于numpy直接求根的结果。import numpy as np from scipy.optimize import root_scalar poly = np.polynomial.Polynomial([4.383930e+00, 2.277144e+14, -7.008406e+25, -4.258004e+16]) # 锁定小量级根的区间求解 res = root_scalar(poly, bracket=[-1e-10, 1e-10], method='bisect') print(res.root, poly(res.root)) - 方案3:采用高精度运算
对精度要求极高的场景,可以使用mpmath等高精度计算库实现多项式求根,用计算速度换取精度,完全规避双精度浮点的精度限制。
内容的提问来源于stack exchange,提问作者user9413641
相关产品推荐
相关产品推荐

