我目前使用Python 2.7.3,sympy 0.7.1.rc1 我正在构建两个这样的矩阵:
import sympy as sp
A = sp.Matrix([[0,0,1],[0,1,0],[1,0,0]])
B = sp.Matrix([[0,0,1],[0,1,0],[1,0,0]])
print A
print B
print A==B
print hash(A)
print hash(B)
结果是...
[0, 0, 1]
[0, 1, 0]
[1, 0, 0]
[0, 0, 1]
[0, 1, 0]
[1, 0, 0]
True
3144597
3144601
A、B 的哈希值不同。我需要将这两个矩阵放入 set() 中,但哈希值不同,然后我无法执行我的意图。 这是同情的错误还是我应该采取另一种方式?
正如评论者所指出的,您需要更新到较新版本的 SymPy。在旧版本中,可变矩阵是可散列的,这是不正确的。现在,
hash(Matrix([[0,0,1],[0,1,0],[1,0,0]]))
会按照应有的方式提高 TypeError
。如果您想要一个可散列矩阵,请使用 ImmutableMatrix
。
对
sympy
矩阵进行哈希处理问题的一个实用解决方案是将矩阵传递给 sp.simplify()
(返回一个 ImmutableDenseMatrix
),调用 evalf
方法,并对结果进行哈希处理:
import sympy as sp
A = sp.Matrix([[0,0,1],[0,1,0],[1,0,0]])
B = sp.Matrix([[0,0,1],[0,1,0],[1,0,0]])
print(hash(sp.simplify(A).evalf())) # >>> 4987893712874514770
print(hash(sp.simplify(B).evalf())) # >>> 4987893712874514770
print(type(A)) # >>> <class 'sympy.matrices.dense.MutableDenseMatrix'>
print(type(sp.simplify(A))) # >>> <class 'sympy.matrices.immutable.ImmutableDenseMatrix'>
print(type(sp.simplify(A).evalf())) # >>> <class 'sympy.matrices.immutable.ImmutableDenseMatrix'>
作为何时需要
evalf
的示例,请考虑 a = sqrt(2) + sqrt(3)
。计算 a^2
并化简得到 a^2 = 5 = 2*sqrt(6)
,因此再次开平方得到 a = sqrt(5 + 2*sqrt(6))
。通过评估这两个表达式之间的差异,sympy
知道这些数字是相等的,但哈希值是不同的,除非使用.evalf()
:
a = sp.sqrt(2) + sp.sqrt(3)
b = sp.sqrt(5 + 2*sp.sqrt(6))
print(sp.simplify(a - b)) # >>> 0
print(hash(sp.simplify(a))) # >>> 5078824210580610210
print(hash(sp.simplify(b))) # >>> 1941379121012922090
print(hash(sp.simplify(a).evalf())) # >>> -6599331494183888331
print(hash(sp.simplify(b).evalf())) # >>> -6599331494183888331