1 | initial version |
The pythonic way of doing this with lists is to use "list comprehensions":
sage: S=[matrix(2,2,[1,i,0,1],mutable=False) for i in [1..3]]
sage: S
[
[1 1] [1 2] [1 3]
[0 1], [0 1], [0 1]
]
sage: m=matrix(2,2,[0,-1,1,0])
sage: [m*s for s in S]
[
[ 0 -1] [ 0 -1] [ 0 -1]
[ 1 1], [ 1 2], [ 1 3]
]
This is probably what you should use, since it gives you a concise syntax and usually gives you the best performance in python. If you write "multiply by m" as a function you have some other syntax available:
sage: g=lambda s:m*s
sage: [g(s) for s in S]
[
[ 0 -1] [ 0 -1] [ 0 -1]
[ 1 1], [ 1 2], [ 1 3]
]
sage: map(g,S)
[
[ 0 -1] [ 0 -1] [ 0 -1]
[ 1 1], [ 1 2], [ 1 3]
]
Via the same idiom you can define a function that takes a list as its argument, but since list comprehension and the "map" functionality are so concise, you probably shouldn't unless you have a compelling mathematical reason for doing so.
sage: f= lambda S: [d*s for s in S]
sage: f(S)
[
[ 0 -1] [ 0 -1] [ 0 -1]
[ 1 1], [ 1 2], [ 1 3]
]
Note that I talked about lists here, not sets. There is a complication with sets and matrices: matrices are by default mutable and mutable elements don't want to be in a set (it'd be hard to find them if they mutate!):
sage: S={matrix(2,2,[1,i,0,1],mutable=False) for i in [1..3]}
TypeError: mutable matrices are unhashable
You can jump through some hoops to make this work:
sage: def immutable_matrix(*args,**kwargs):
....: m=matrix(*args,**kwargs)
....: m.set_immutable()
....: return m
....:
sage: S={immutable_matrix(2,2,[1,i,0,1],mutable=False) for i in [1..3]}
sage: S
{[1 1]
[0 1], [1 2]
[0 1], [1 3]
[0 1]}
Everything we discussed before still works, except that new matrices will by default be mutable again:
sage: [d*s for s in S]
[
[ 0 -1] [ 0 -1] [ 0 -1]
[ 1 3], [ 1 2], [ 1 1]
]
sage: {d*s for s in S}
TypeError: mutable matrices are unhashable
sage: {immutable_matrix(d*s) for s in S}
{[ 0 -1]
[ 1 1], [ 0 -1]
[ 1 2], [ 0 -1]
[ 1 3]}
The map idiom still works, but will produce a list. You might try set(map(g,S))
but then you have to adjust g
to produce immutable matrices. Mutatis mutandis, you can still wrap this into a function f
that takes a set/list as input.
2 | No.2 Revision |
The pythonic way of doing this with lists is to use "list comprehensions":
sage: S=[matrix(2,2,[1,i,0,1],mutable=False) S=[matrix(2,2,[1,i,0,1]) for i in [1..3]]
sage: S
[
[1 1] [1 2] [1 3]
[0 1], [0 1], [0 1]
]
sage: m=matrix(2,2,[0,-1,1,0])
sage: [m*s for s in S]
[
[ 0 -1] [ 0 -1] [ 0 -1]
[ 1 1], [ 1 2], [ 1 3]
]
This is probably what you should use, since it gives you a concise syntax and usually gives you the best performance in python. If you write "multiply by m" as a function you have some other syntax available:
sage: g=lambda s:m*s
sage: [g(s) for s in S]
[
[ 0 -1] [ 0 -1] [ 0 -1]
[ 1 1], [ 1 2], [ 1 3]
]
sage: map(g,S)
[
[ 0 -1] [ 0 -1] [ 0 -1]
[ 1 1], [ 1 2], [ 1 3]
]
Via the same idiom you can define a function that takes a list as its argument, but since list comprehension and the "map" functionality are so concise, you probably shouldn't unless you have a compelling mathematical reason for doing so.
sage: f= lambda S: [d*s for s in S]
sage: f(S)
[
[ 0 -1] [ 0 -1] [ 0 -1]
[ 1 1], [ 1 2], [ 1 3]
]
Note that I talked about lists here, not sets. There is a complication with sets and matrices: matrices are by default mutable and mutable elements don't want to be in a set (it'd be hard to find them if they mutate!):
sage: S={matrix(2,2,[1,i,0,1],mutable=False) S={matrix(2,2,[1,i,0,1]) for i in [1..3]}
TypeError: mutable matrices are unhashable
You can jump through some hoops to make this work:
sage: def immutable_matrix(*args,**kwargs):
....: m=matrix(*args,**kwargs)
....: m.set_immutable()
....: return m
....:
sage: S={immutable_matrix(2,2,[1,i,0,1],mutable=False) S={immutable_matrix(2,2,[1,i,0,1]) for i in [1..3]}
sage: S
{[1 1]
[0 1], [1 2]
[0 1], [1 3]
[0 1]}
Everything we discussed before still works, except that new matrices will by default be mutable again:
sage: [d*s for s in S]
[
[ 0 -1] [ 0 -1] [ 0 -1]
[ 1 3], [ 1 2], [ 1 1]
]
sage: {d*s for s in S}
TypeError: mutable matrices are unhashable
sage: {immutable_matrix(d*s) for s in S}
{[ 0 -1]
[ 1 1], [ 0 -1]
[ 1 2], [ 0 -1]
[ 1 3]}
The map idiom still works, but will produce a list. You might try set(map(g,S))
but then you have to adjust g
to produce immutable matrices. Mutatis mutandis, you can still wrap this into a function f
that takes a set/list as input.