首先,我使用 numpy.linalg.eigvalsh
找到 (4000x4000) 矩阵的特征值。然后,我更改边界条件,预计特征值只会发生微小变化。
减去特征值容易受到浮点误差的影响,因此我使用了一些相对容差。
现在假设我有一个特征值A = 1.0001e-10
,另一个B = 1.0050e-10
。根据我对浮点运算的拙见,A - B != 0
.问题是,这些数字来自涉及许多数量级的线性代数计算。例如,其他特征值可能是1
顺序的。
问题是,使用numpy.linalg.eigvalsh
计算的特征值的精度是多少?此精度是相对于值 ( A * eps
),还是相对于最大特征值?或者也许相对于原始矩阵的元素?
例如,此矩阵:
1 1e-20
1e-20 3
给出与此相同的特征值:
1 1e-5
1e-5 3
我不确定 Lapack 是否在 eigvalsh 下面使用,但这可能会很有趣:
对称/非对称特征问题的 Lapack 误差边界:
http://www.netlib.org/lapack/lug/node89.html
http://www.netlib.org/lapack/lug/node91.html
首先,求解器不精确。其次,您的示例矩阵条件较差:对角线元素比非对角线元素大几个数量级。这总是会导致数字问题。
从简单代数来看,第二个矩阵的行列式是(1 * 3) - (1e5 * 1e5) = 3 - 1e-10
。您已经可以看到精度问题实际上是最小元素精度的两倍。(这同样适用于特征值。即使 linalg 使用双精度,因为求解器是近似的,你会得到相同的答案。如果将小值更改为1e-3
则开始看到差异,因为现在精度在数值近似值的量级上。
这个具体问题以前已经问过了。您可以在此答案中看到如何使用 sympy 以任意精度求解特征值。