Updated question:
I would like to define a generic symbolic function called s whose arguments are totally symmetric.
So if I type s(3,2) the output must be s(2,3),
sage: s(3,2)
s(2,3)
and similarly
sage: s(3,4,1,2)
s(1,2,3,4)
and in general some arbitrary product
sage: s(3,2)*s(1,2)^2*s(5,4,1)
s(2,3)*s(1,2)^2*s(1,4,5)
Is it possible to have such a definition? It would be nice if there was an argument to the built-in function()
to specify the symmetry of its arguments. In this case I would get what I want with something like
s = function('s', sym='symmetric')
Partial solution Solution from Apr/2017:
Upon reading Sage's source code I noticed the 'eval_func' option when defining functions. So I get (almost) what I want if I define this function(following a suggestion of mforets, thanks!):
def symmetric(self, x1,x2):
*x):
L = list(x)
L0 = copy(L)
L.sort()
if x1 < x2:
L0 <= L:
pass
else:
return self(x2,x1)
self(*L)
and use it together with 'eval_func'define the (Mandelstam invariant) s
as follows
s = function("s", eval_func=symmetric)
Doing this works in the special case when the function contains two arguments:everything works. For example
sage: 2*s(2,1)*s(6,5)^2
2*s(5, 2*s(2,1)*s(6,5,4,3)^2
2*s(3, 4, 5, 6)^2*s(1, 2)
So the I consider this question now becomes: how can I extend this definition to a function with an arbitrary number of arguments?
Update 2:
For the moment I am using a less generic version as follows:
def symmetric(self, *x):
L = [i for i in x]
L0 = copy(L)
L.sort()
# to avoid a recursion
if L0 <= L or len(L0) == 6:
pass
else:
size = len(L)
if size == 2:
return self(L[0],L[1])
elif size == 3:
return self(L[0],L[1],L[2])
elif size == 4:
return self(L[0],L[1],L[2],L[3])
elif size == 5:
return self(L[0],L[1],L[2],L[3],L[4])
I tried to make it generic with
if L0 <= L:
pass
else:
return self(tuple(L))
but this doesn't work because the argument to self
should be e.g. 1,2,3
and not the tuple (1,2,3)
.closed!