Python 相同的SciPy.linalg.eigh()特征值不相等
我使用Python2.7、NUMPY1.6.2和SCIPY0.16.0来计算以下内容 我创建了一个哈达玛矩阵。然后我从矩阵的第0,2,4个向量中创建了外积,并将它们相加,使对角线为0。然后我使用SciPy.linalg.eigh()计算了特征值。它是退化的。前两个特征值相同,即-3。但当我用Python检查时,它说它们不一样。代码如下所示Python 相同的SciPy.linalg.eigh()特征值不相等,python,numpy,scipy,linear-algebra,eigenvalue,Python,Numpy,Scipy,Linear Algebra,Eigenvalue,我使用Python2.7、NUMPY1.6.2和SCIPY0.16.0来计算以下内容 我创建了一个哈达玛矩阵。然后我从矩阵的第0,2,4个向量中创建了外积,并将它们相加,使对角线为0。然后我使用SciPy.linalg.eigh()计算了特征值。它是退化的。前两个特征值相同,即-3。但当我用Python检查时,它说它们不一样。代码如下所示 from scipy import linalg as sp import numpy from numpy import linalg as np def
from scipy import linalg as sp
import numpy
from numpy import linalg as np
def get_outer_product(vector):
length = len(vector)
outer_product = [[0 for x in range(length)] for x in range(length)]
for i in range(0, length):
for j in range(0, length):
if i == j:
outer_product[i][j] = 0
continue
outer_product[i][j] = vector[i] * vector[j]
return outer_product
def test():
hadamard_matrix = sp.hadamard(8)
sum_of_outer_products = [map(sum, zip(*t)) for t in zip(get_outer_product(hadamard_matrix[0]), get_outer_product(hadamard_matrix[2]))]
sum_of_outer_products = [map(sum, zip(*t)) for t in zip(sum_of_outer_products, get_outer_product(hadamard_matrix[4]))]
e_vals, e_vecs = sp.eigh(sum_of_outer_products)
print str(e_vals[0]) + " == " + str(e_vals[0]) + "?"
print e_vals[0] == e_vals[1]
输出为:
Python 2.7 (r27:82525, Jul 4 2010, 09:01:59) [MSC v.1500 32 bit (Intel)] on win32
>>> import scipytest
>>> scipytest.test()
-3.0 == -3.0?
False
我做错了什么?
使用浮点数时,请务必小心使用equal运算符,并记住可能存在精度问题和:
顺便说一下,在我的机器上,这两种情况下都返回true:
-3.0 == -3.0?
True
True
可以打印数组和类型的实际值吗。它没有返回一个复杂的类型或其他东西,对吗?你确定要比较两个浮点值吗?我使用的是NumPy 1.6.2。@OmarShehab那么你要么更新你的库,要么实现你自己版本的
isclose()
,它只是检查一个浮点数是否近似等于另一个浮点数,特别是看到文档解释了isclose
是如何实现的:absolute(a-b)由于其他依赖关系,我无法升级NumPy。你知道为什么打印e_vals[0]==e_vals[1]的输出在你这边是不同的吗?@OmarShehab这些只是猜测,但是eig*
使用了一些数值收敛算法,它并不总是收敛到完全相同的点(可能是-3.0000000000000000 18)由于浮点不准确,这两个数字是不一样的。事实上,你现在已经注意到了,而不是在一个更大的项目的中间。我建议永远不要使用浮点相等运算符并实现自己版本的浮点相等。@OmarShehab我非常怀疑eig
函数是否从1.6.2版更改为1.7版。它可能恰好收敛到-3。但即使在这种情况下,我也不会使用e_vals[0]==e_vals[1]
代码,并且仍然会使用isclose或我自己的isclose实现。
-3.0 == -3.0?
True
True