I have lots of matrices (as result of rotations, etc.), but I would be sure to store them only once. I thought about using a set :

``print set([np.matrix([[0, 0],[0, 1],[1, 1],[2, 1]]),np.matrix([[0, 0],[1, 0],[1, -1],[1, -2]])])``

Unfortunately, I get :

TypeError: unhashable type: 'matrix'

It's sad because a set would be exactly the right data type to avoid repetitions, and be able to use union, intersection, etc.

How to work with sets of matrices in Python?

``````In [299]: m1
Out[299]:
matrix([[0, 0],
[0, 1],
[1, 1],
[2, 1]])

In [300]: m2
Out[300]:
matrix([[ 0,  0],
[ 1,  0],
[ 1, -1],
[ 1, -2]])

In [297]: set([tuple(m1.A1),tuple(m2.A1)])
Out[297]: {(0, 0, 0, 1, 1, 1, 2, 1), (0, 0, 1, 0, 1, -1, 1, -2)}
``````

`m1.A1` converts the matrix to a 1d array, which displays as a simple list. Wrap that in `tuple` makes an object that is hashable.

A `set` is like a dictionary with keys but no values. Both provide quick access (and `in` testing) by converting each key to a 'hash'. Part of why it requires a tuple, as opposed to a list is that it must be immutable. The hash would change if you changed one of the values of the matrix.

Without the `A1` (or other ravel) it does not work - look at `tuple(m1)`.

``````In [302]: set([tuple(m1),tuple(m2)])
...
TypeError: unhashable type: 'matrix'

In [303]: tuple(m1)
Out[303]: (matrix([[0, 0]]), matrix([[0, 1]]), matrix([[1, 1]]), matrix([[2, 1]]))
``````

We could also convert the matrix to some string representation, and store that. Note that these conversions don't save you space, and all incur a conversion cost.

We may need to explore how these matrices are compared. What makes one different from another?

Equality of matching elements:

``````In [306]: m1==m2
Out[306]:
matrix([[ True,  True],
[False, False],
[ True, False],
[False, False]], dtype=bool)

In [307]: (m1==m2).all()
Out[307]: False

In [308]: (m1==m1).all()
Out[308]: True
``````

Of course that requires that they all be the same shape.

If the shapes differ it can't do element by element comparisons, so it returns a boolean scalar.

``````In [309]: m1==m1.T
Out[309]: False
``````

You could compare the object ids

``````In [314]: set([id(m1),id(m2),id(m2[:])])
Out[314]: {3029619684, 3036025828, 3036825892}
``````

but it doesn't capture the equality of views (`m2[:]` has the same values, but is a different object).

Also if I change a value, e.g. `m2[2,1]=1`, it does not change the `id`, but would change the `tuple(m2.A1)` hash, and equality tests.

Top