# Revision history [back]

First, let me expliain how to deal with lists instead of sets, because there is a trick with sets:

You an create your matrices as follows:

sage: a = matrix(ZZ,[[1,2],[3,4]])
sage: b = matrix(ZZ,[[5,6],[7,8]])
sage: c = matrix(ZZ,[[1,2],[3,4]])
sage: d = matrix(ZZ,[[0,1],[1,0]])


Then, you can create the list of matrices as follows:

sage: L = [a,b,c]
sage: L
[
[1 2]  [5 6]  [1 2]
[3 4], [7 8], [3 4]
]


You can define the other list with list comprehension, which is a nice feature of Python:

sage: d = matrix(ZZ,[[0,1],[1,0]])
sage: [d*i for i in L]
[
[3 4]  [7 8]  [3 4]
[1 2], [5 6], [1 2]
]


Now, you noticed that c is equal to a and since you want a set, not a list, you would like Sage to keep only one occurence in the set.

You should be able to define a set as follows:

sage: S = {a,b,c}
TypeError: mutable matrices are unhashable


The error message tells you that the matrices must be immutable to enter a set. Indeed:

sage: a.is_mutable()
True


So, you can make your matrices immutable first as follows:

sage: a.set_immutable()
sage: b.set_immutable()
sage: c.set_immutable()
sage: d.set_immutable()


Then you can define your set:

sage: S = {a,b,c}
sage: S
{[1 2]
[3 4], [5 6]
[7 8]}


As you can see, there are only to elements in it:

sage: len(S)
2


Now, you shoud be able to define yous second set by comprehension as we did with lists:

sage: {d*i for i in S}
TypeError: mutable matrices are unhashable


You get the same error. Indeed, when we construct a new matrix, it is mutable by default, and there is no way to construct an immutable one from the beginning (at least this is not documented). So, even if a and d are immutable, d*a is mutable.

A workaround is to define a mutabilize function that returns an immutable copy of a mutable matrix:

sage: def mutabilize(m):
....:     M = copy(m)
....:     M.set_immutable()
....:     return M


So, at the end you get:

sage: {mutabilize(d*i) for i in S}
{[3 4]
[1 2], [7 8]
[5 6]}


First, let me expliain how to deal with lists instead of sets, because there is a trick with sets:

You an create your matrices as follows:

sage: a = matrix(ZZ,[[1,2],[3,4]])
sage: b = matrix(ZZ,[[5,6],[7,8]])
sage: c = matrix(ZZ,[[1,2],[3,4]])
sage: d = matrix(ZZ,[[0,1],[1,0]])


Then, you can create the list of matrices as follows:

sage: L = [a,b,c]
sage: L
[
[1 2]  [5 6]  [1 2]
[3 4], [7 8], [3 4]
]


You can define the other list with list comprehension, which is a nice feature of Python:

sage: d = matrix(ZZ,[[0,1],[1,0]])
sage: [d*i for i in L]
[
[3 4]  [7 8]  [3 4]
[1 2], [5 6], [1 2]
]


Now, you noticed that c is equal to a and since you want a set, not a list, you would like Sage to keep only one occurence in the set.

You should be able to define a set as follows:

sage: S = {a,b,c}
TypeError: mutable matrices are unhashable


The error message tells you that the matrices must be immutable to enter a set. Indeed:

sage: a.is_mutable()
True


So, you can make your matrices immutable first as follows:

sage: a.set_immutable()
sage: b.set_immutable()
sage: c.set_immutable()
sage: d.set_immutable()


Then you can define your set:

sage: S = {a,b,c}
sage: S
{[1 2]
[3 4], [5 6]
[7 8]}


As you can see, there are only to elements in it:

sage: len(S)
2


Now, you shoud be able to define yous second set by comprehension as we did with lists:

sage: {d*i for i in S}
TypeError: mutable matrices are unhashable


You get the same error. Indeed, when we construct a new matrix, it is mutable by default, and there is no way to construct an immutable one from the beginning (at least this is not documented). So, even if a and d are immutable, d*a is mutable.mutable. I agree that this is not very handy.

A workaround is to define a mutabilize function that returns an immutable copy of a mutable matrix:

sage: def mutabilize(m):
....:     M = copy(m)
....:     M.set_immutable()
....:     return M


So, at the end you get:

sage: {mutabilize(d*i) for i in S}
{[3 4]
[1 2], [7 8]
[5 6]}


First, let me expliain how to deal with lists instead of sets, because there is a trick with sets:

You an create your matrices as follows:

sage: a = matrix(ZZ,[[1,2],[3,4]])
sage: b = matrix(ZZ,[[5,6],[7,8]])
sage: c = matrix(ZZ,[[1,2],[3,4]])
sage: d = matrix(ZZ,[[0,1],[1,0]])


Then, you can create the list of matrices as follows:

sage: L = [a,b,c]
sage: L
[
[1 2]  [5 6]  [1 2]
[3 4], [7 8], [3 4]
]


You can define the other list with list comprehension, which is a nice feature of Python:

sage: d = matrix(ZZ,[[0,1],[1,0]])
sage: [d*i for i in L]
[
[3 4]  [7 8]  [3 4]
[1 2], [5 6], [1 2]
]


Now, you noticed that c is equal to a and since you want a set, not a list, you would like Sage to keep only one occurence in the set.

You should be able to define a set as follows:

sage: S = {a,b,c}
TypeError: mutable matrices are unhashable


The error message tells you that the matrices must be immutable to enter a set. Indeed:

sage: a.is_mutable()
True


So, you can make your matrices immutable first as follows:

sage: a.set_immutable()
sage: b.set_immutable()
sage: c.set_immutable()
sage: d.set_immutable()


Then you can define your set:

sage: S = {a,b,c}
sage: S
{[1 2]
[3 4], [5 6]
[7 8]}


As you can see, there are only to elements in it:

sage: len(S)
2


Now, you shoud be able to define yous second set by comprehension as we did with lists:

sage: {d*i for i in S}
TypeError: mutable matrices are unhashable


You get the same error. Indeed, when we construct a new matrix, it is mutable by default, and there is no way to construct an immutable one from the beginning (at least this is not documented). So, even if a and d are immutable, d*a is mutable. I agree that this is not very handy.

A workaround is to define a mutabilizeimmutabilize function that returns an immutable copy of a mutable matrix:

sage: def mutabilize(m):
immutabilize(m):
....:     M = copy(m)
....:     M.set_immutable()
....:     return M


So, at the end you get:

sage: {mutabilize(d*i) {immutabilize(d*i) for i in S}
{[3 4]
[1 2], [7 8]
[5 6]}


First, let me expliain explain how to deal with lists instead of sets, because there is a trick with sets:

You an create your matrices as follows:

sage: a = matrix(ZZ,[[1,2],[3,4]])
sage: b = matrix(ZZ,[[5,6],[7,8]])
sage: c = matrix(ZZ,[[1,2],[3,4]])
sage: d = matrix(ZZ,[[0,1],[1,0]])


Then, you can create the list of matrices as follows:

sage: L = [a,b,c]
sage: L
[
[1 2]  [5 6]  [1 2]
[3 4], [7 8], [3 4]
]


You can define the other list with list comprehension, which is a nice feature of Python:

sage: d = matrix(ZZ,[[0,1],[1,0]])
sage: [d*i for i in L]
[
[3 4]  [7 8]  [3 4]
[1 2], [5 6], [1 2]
]


Now, you noticed that c is equal to a and since you want a set, not a list, you would like Sage to keep only one occurence in the set.

You should be able to define a set as follows:

sage: S = {a,b,c}
TypeError: mutable matrices are unhashable


The error message tells you that the matrices must be immutable to enter a set. Indeed:

sage: a.is_mutable()
True


So, you can make your matrices immutable first as follows:

sage: a.set_immutable()
sage: b.set_immutable()
sage: c.set_immutable()
sage: d.set_immutable()


Then you can define your set:

sage: S = {a,b,c}
sage: S
{[1 2]
[3 4], [5 6]
[7 8]}


As you can see, there are only to elements in it:

sage: len(S)
2


Now, you shoud be able to define yous second set by comprehension as we did with lists:

sage: {d*i for i in S}
TypeError: mutable matrices are unhashable


You get the same error. Indeed, when we construct a new matrix, it is mutable by default, and there is no way to construct an immutable one from the beginning (at least this is not documented). So, even if a and d are immutable, d*a is mutable. I agree that this is not very handy.

A workaround is to define a immutabilize function that returns an immutable copy of a mutable matrix:

sage: def immutabilize(m):
....:     M = copy(m)
....:     M.set_immutable()
....:     return M


So, at the end you get:

sage: {immutabilize(d*i) for i in S}
{[3 4]
[1 2], [7 8]
[5 6]}