NumPy中的精度:比较数字时的问题

2022-04-12 00:00:00 python numpy linear-algebra

问题描述

先来了解一下背景知识。我正在找一个实对称矩阵的特征值和特征向量,其中行之和为0。更具体地说,一旦我找到一个特征向量,我就使用$argsort$来找到对其中一个特征值进行排序的排列,并将该排列应用于原始矩阵。

现在,我使用NumPy包用python语言实现了代码。代码本身是递归的,如果它在特征向量中找到一组相等的值,它就提取与我们具有相等值的索引对应的对称子矩阵,并在该矩阵上重新应用该算法。

虽然这一切都很好,而且主要是繁琐的工作,但当一组本应对应于特征向量中相等条目的索引没有被识别为具有相等的值时,我感到惊讶。问题是,这些值是通过某种算法(可能是Lanczos,但我并不完全熟悉NumPy)计算到机器精度的。这是一个样例输出,其中我显式地检查了特征向量中两个条目之间的差异:

    >>> T=spectral.seriation(A,index)

    columns [ 0  1  2  3  4  5  6  7  8  9 10 11]

    [  3.30289130e-01  -2.75240941e-01  -2.75240941e-01   3.30289130e-01
    -2.75240941e-01   3.30289130e-01  -2.75240941e-01   3.30289130e-01
    3.30289130e-01  -2.75240941e-01  -1.69794463e-16  -2.75240941e-01]

    [ 4  6  9  1  2 11 10  0  5  7  8  3]

    difference   -5.55111512313e-17

例程Seriation()是一个递归函数。浮点数组是所考虑的特征向量,下面的数组给出列的排序顺序。请注意,列[4,6,9,1,2,11]具有相同的值。然而,特征向量和特征值计算总是近似值,实际上,当我输出第9列和第2列中的条目之间的差异时,它是非零的。在算法应该对[4,6,9,1,2,11]分组的地方,它只对[4,6,9]分组,而将其余的放在另一组中,这让工作变得很困难。

所以问题是:有没有一种方法可以在NumPy中执行任意精度的计算?如果做不到这一点,解决此问题的好办法是什么?

另外,我可能应该提一下,可以从数学上证明这些条目必须相等。这是矩阵的一个性质,但希望与问题无关。


解决方案

双精度数不完全是实数[甚至不是有理数]。在每个范围[确切地说,每个范围至少有两个元素]中都有无限数量的有理数,但只有有限数量的比特来表示它们。
因此,对于"精确"计算,您应该会有一些舍入误差。

有关更多信息,您可能需要阅读what every computer scientist should know about floating-point arithmetic

相关文章