I'm trying to implement some extended functionality with simplicial complexes and have several questions about group actions in Sage. Any help with any of the following would be greatly appreciated!
1. Group actions on nested lists, sets, tuples etc.
In Magma, I can apply a permutation to an arbitrarily nested object of sets, sequences etc. without having to know what exactly that object is. For example,
>> [{[1,2],[4,5]},{[4,5]}] ^ Sym(5)!(1,2,3,4);
applies the permutation to a list of sets of lists. GAP is slightly less flexible, providing functions such as OnTuples
, OnTuplesTuples
, OnSetsTuples
which deal with specific cases, but you have to know "in advance" what sort of object you are acting on. As far as I can see Sage hasn't got functions like these at all.
The simplicial complexes can take various forms which would each require a different type of action; for example, the vertices could be integers, or tuples (for example in the case of a Chessboard complex the vertices are coordinates on a chessboard), or sets.
I don't mind calling GAP functions, but would rather avoid calling Magma functions so that code I write can be used by those who don't have access to Magma. Am I missing a simple way of acting on such objects in Sage, or do I need to write my own code dealing with each case separately?
2. Registering group actions in Sage
Once I have defined my action with a function I'd like to register it so I can apply permutations to simplices using x * g
. I have tried to follow the syntax explained in the docs here: (I cannot post links, search for register_action
in the doc entitled Base class for parent objects
.) A minimal example follows:
import sage.categories.action
import operator
def chessboard(n, m):
k = min(n, m)
row_tups = [tuple(x) for x in Subsets([1..n], k)]
col_tups = [tuple(x) for x in Permutations([n+1..n+m], k)]
placements = cartesian_product([row_tups, col_tups])
placements_as_sets = [{(p[0][i],p[1][i]) for i in range(k)} \
for p in placements]
G = SymmetricGroup(n+m)
A = G.stabilizer([1..n], "OnSets")
return SimplicialComplex(placements_as_sets), A
class ChessboardAction(sage.categories.action.Action):
def __init__(self, G, C, is_left=True):
sage.categories.action.Action.__init__(self, G, C, is_left,
operator.mul)
def _act_(self, g, c):
new = set(tuple([g(i) for i in x]) for x in c)
out = next(f for f in C.faces()[c.dimension()] if set(f) == new)
return out
C, G = chessboard(3, 4)
act = ChessboardAction(G, C)
g = G.an_element()
c = C.an_element()
act(g, c)
This fails with error:
NotImplementedError Traceback (most recent call last)
<ipython-input-69-7155e64e7004> in <module>()
----> 1 load("chessboard.sage")
sage/structure/sage_object.pyx in sage.structure.sage_object.load (build/cythonized/sage/structure/sage_object.c:12879)()
/usr/lib/python2.7/dist-packages/sage/repl/load.pyc in load(filename, globals, attach)
245 if attach:
246 add_attached_file(fpath)
--> 247 exec(preparse_file(open(fpath).read()) + "\n", globals)
248 elif ext == '.spyx' or ext == '.pyx':
249 if attach:
<string> in <module>()
sage/categories/action.pyx in sage.categories.action.Action.__call__ (build/cythonized/sage/categories/action.c:3602)()
sage/categories/action.pyx in sage.categories.action.Action._call_ (build/cythonized/sage/categories/action.c:3864)()
NotImplementedError: Action not implemented.
I then tried to implement a simple action on another object but received the same error, so perhaps I am misunderstanding the method:
class TestAction(sage.categories.action.Action):
def __init__(self, G, S, is_left=True):
sage.categories.action.Action.__init__(self, G, S, is_left,
operator.mul)
def _act_(self, g, s):
return Set([g(i) for i in s])
G = SymmetricGroup(4)
S = Subsets([1..4], 3)
act = TestAction(G, S)
g = G.an_element()
s = S.an_element()
act(g, s)
This fails with the same error as above.