I have attached a patch that follows a totally different approach: Use `UniqueRepresentation`

as a base class for matrix spaces!

Advantage: One gets `__hash__`

, `__cmp__`

and `__reduce__`

for free, and the hash is even faster than with my previous patch.

sage: M = MatrixSpace(ZZ, 10)
sage: N = MatrixSpace(ZZ, 10,sparse=True)
sage: M == N
False
sage: timeit("hash(M)", number=10^6)
1000000 loops, best of 3: 511 ns per loop

The price to pay (as one can see in the example): The spaces of dense versus sparse matrices are not considered equal anymore. For applications, this shouldn't matter, since the coercion model can easily deal with it. In fact, I like the new behaviour a lot better than the old behaviour!

Old:

sage: M = MatrixSpace(ZZ, 10)
sage: N = MatrixSpace(ZZ, 10,sparse=True)
sage: a = M.random_element()
sage: b = N.random_element()
sage: (a+b).parent()
Full MatrixSpace of 10 by 10 dense matrices over Integer Ring
sage: (b+a).parent()
Full MatrixSpace of 10 by 10 sparse matrices over Integer Ring

The parent of the sum depends on the order of summands!!

But with the new patch, one has

sage: M = MatrixSpace(ZZ, 10)
sage: N = MatrixSpace(ZZ, 10,sparse=True)
sage: a = M.random_element()
sage: b = N.random_element()
sage: (a+b).parent()
Full MatrixSpace of 10 by 10 dense matrices over Integer Ring
sage: (b+a).parent()
Full MatrixSpace of 10 by 10 dense matrices over Integer Ring

independent of the summation order.

I had to change some existing doctests in a trivial way, and then the whole test suite passes. Ready for review!

Apply trac12290_unique_matrix_space.patch