| 266 | | return self._hash() |
|---|
| | 266 | """ |
|---|
| | 267 | EXAMPLE: |
|---|
| | 268 | sage: B = random_matrix(GF(127),3,3) |
|---|
| | 269 | sage: B.set_immutable() |
|---|
| | 270 | sage: {B:0} # indirect doctest |
|---|
| | 271 | {[ 9 75 94] |
|---|
| | 272 | [ 4 57 112] |
|---|
| | 273 | [ 59 85 45]: 0} |
|---|
| | 274 | |
|---|
| | 275 | sage: M = random_matrix(GF(7), 10, 10) |
|---|
| | 276 | sage: M.set_immutable() |
|---|
| | 277 | sage: hash(M) |
|---|
| | 278 | 143 |
|---|
| | 279 | sage: MZ = M.change_ring(ZZ) |
|---|
| | 280 | sage: MZ.set_immutable() |
|---|
| | 281 | sage: hash(MZ) |
|---|
| | 282 | 143 |
|---|
| | 283 | sage: MS = M.sparse_matrix() |
|---|
| | 284 | sage: MS.set_immutable() |
|---|
| | 285 | sage: hash(MS) |
|---|
| | 286 | 143 |
|---|
| | 287 | |
|---|
| | 288 | TEST: |
|---|
| | 289 | sage: A = matrix(GF(2),2,0) |
|---|
| | 290 | sage: hash(A) |
|---|
| | 291 | Traceback (most recent call last): |
|---|
| | 292 | ... |
|---|
| | 293 | TypeError: mutable matrices are unhashable |
|---|
| | 294 | sage: A.set_immutable() |
|---|
| | 295 | sage: hash(A) |
|---|
| | 296 | 0 |
|---|
| | 297 | """ |
|---|
| | 298 | if self.is_mutable(): |
|---|
| | 299 | raise TypeError("mutable matrices are unhashable") |
|---|
| | 300 | x = self.fetch('hash') |
|---|
| | 301 | if not x is None: |
|---|
| | 302 | return x |
|---|
| | 303 | |
|---|
| | 304 | cdef unsigned long _hash = 0 |
|---|
| | 305 | cdef Py_ssize_t i |
|---|
| | 306 | |
|---|
| | 307 | if self._nrows == 0 or self._ncols == 0: |
|---|
| | 308 | return 0 |
|---|
| | 309 | |
|---|
| | 310 | for i from 0 <= i < self._nrows * self._ncols: |
|---|
| | 311 | _hash ^= (i * self._entries[i]) |
|---|
| | 312 | |
|---|
| | 313 | if _hash == -1: |
|---|
| | 314 | return -2 |
|---|
| | 315 | |
|---|
| | 316 | self.cache('hash', _hash) |
|---|
| | 317 | |
|---|
| | 318 | return _hash |
|---|