Reputation: 510
I am currently using Python 2.7.3, sympy 0.7.1.rc1 I am constructing two matrices like this:
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)
and the result is...
[0, 0, 1]
[0, 1, 0]
[1, 0, 0]
[0, 0, 1]
[0, 1, 0]
[1, 0, 0]
True
3144597
3144601
The hash value of A,B are different. I need to put these two matrix into a set(), but the hash value are different and then I am unable to do what I intended for. Is it a bug of sympy or I should do it another way?
Upvotes: 1
Views: 544
Reputation: 1742
A practical solution to the problem of hashing a sympy
matrix is to pass the matrix to sp.simplify()
(which returns an ImmutableDenseMatrix
), call the evalf
method, and hash the result:
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'>
As an example of when evalf
is necessary, consider a = sqrt(2) + sqrt(3)
. Calculating a^2
and simplifying gives a^2 = 5 = 2*sqrt(6)
, so taking the square root again gives a = sqrt(5 + 2*sqrt(6))
. Evaluating the difference between these 2 expressions shows that sympy
knows these numbers are equal, but the hash values are different unless .evalf()
is used:
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
Upvotes: 0
Reputation: 91620
As the commenters noted, you need to update to a newer version of SymPy. In older versions, mutable matrices were hashable, which was incorrect. Now, hash(Matrix([[0,0,1],[0,1,0],[1,0,0]]))
raises TypeError
as it should. If you want a hashable matrix, use ImmutableMatrix
.
Upvotes: 2