Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Defining a symmetric function

I am new to Sage (about a week) and I would like to define a symbolic function called s that doesn't evaluate to anything, but it has to be symmetric.

So if I type s(3,2) the output must be s(2,3), or typing s(1,4,3,2) the output must be s(1,2,3,4) etc.

Is it possible to have such a definition? I am searching the documentation to try to implement this, but so far no luck.

I tried using the function sort_subscript() that I found in the tensor.pdf documentation, but the attempt below obviously fails in an infinite loop:

def s(*m): a=sort_subscript(m); return s(a[1]);

How can I implement this? My motivation is that s(i,j) are the symmetric Mandelstam invariants in a scattering amplitude context.

Defining a symmetric function

I am new to Sage (about a week) and I would like to define a symbolic function called s that doesn't evaluate to anything, but it has to be symmetric.

So if I type s(3,2) the output must be s(2,3), or typing s(1,4,3,2) the output must be s(1,2,3,4) etc.

Is it possible to have such a definition? I am searching the documentation to try to implement this, but so far no luck.

I tried using the function sort_subscript() * that I found in the tensor.pdf documentation, but the attempt below obviously fails in an infinite loop:

def s(*m):
    a=sort_subscript(m);
    return s(a[1]);

s(a[1]);

How can I implement this? My motivation is that s(i,j) are the symmetric Mandelstam invariants in a scattering amplitude context.

Defining a symmetric function

I am new to Sage (about a week) and I would like to define a symbolic function called s that doesn't evaluate to anything, but it has to be symmetric.

So if I type s(3,2) the output must be s(2,3), or typing s(1,4,3,2) the output must be s(1,2,3,4) etc.

Is it possible to have such a definition? I am searching the documentation to try to implement this, but so far no luck.

I tried using the function sort_subscript()* that I found in the tensor.pdf documentation, but the attempt below obviously fails in an infinite loop:

def s(*m):
    a=sort_subscript(m);
    return s(a[1]);

How can I implement this? My motivation is that s(i,j) are the symmetric Mandelstam invariants in a scattering amplitude context.

Edit:

Today I tried this:

class s(BuiltinFunction):
    def __init__(self, x1, x2):
        if x2 >= x1:
            self.x = x1
            self.y = x2
            BuiltinFunction.__init__(self,'s(%s,%s)' % (x1,x2))
         else:
             self.x = x2
             self.y = x1
             BuiltinFunction.__init__(self,'s(%s,%s)' % (x2,x1))

And it works in the sense that sage: s(4,2) s(2,4)

However, this is not complete since

sage: 2*s(4,2)
...
TypeError: unsupported operand parent(s) for '*': 'Integer Ring' and '<class '__main__.s'>'

where I would expect the answer 2*s(2,4). So it is not so simple and I couldn't get a working definition for the __mul__ method and it just looked like the wrong approach anyway.

So is it possible to define a symmetric function that behaves like this inside the user interface?

Alternatively, it would be nice if there was an argument to the built-in function() to specify the symmetry,

s = function('s', nargs=2, sym='symmetric')

Defining a symmetric function

I am new to Sage (about a week) and I would like to define a symbolic function called s that doesn't evaluate to anything, but it has to be symmetric.

So if I type s(3,2) the output must be s(2,3), or typing s(1,4,3,2) the output must be s(1,2,3,4) etc.

Is it possible to have such a definition? I am searching the documentation to try to implement this, but so far no luck.

I tried using the function sort_subscript()* that I found in the tensor.pdf documentation, but the attempt below obviously fails in an infinite loop:

def s(*m):
    a=sort_subscript(m);
    return s(a[1]);

How can I implement this? My motivation is that s(i,j) are the symmetric Mandelstam invariants in a scattering amplitude context.

Edit:

Today I tried this:

class s(BuiltinFunction):
    def __init__(self, x1, x2):
        if x2 >= x1:
            self.x = x1
            self.y = x2
            BuiltinFunction.__init__(self,'s(%s,%s)' % (x1,x2))
         else:
             self.x = x2
             self.y = x1
             BuiltinFunction.__init__(self,'s(%s,%s)' % (x2,x1))

And it works in the sense that that

   sage: s(4,2) 
       s(2,4)

s(2,4)

However, this is not complete since

sage: 2*s(4,2)
...
TypeError: unsupported operand parent(s) for '*': 'Integer Ring' and '<class '__main__.s'>'

where I would expect the answer 2*s(2,4). So it is not so simple and I couldn't get a working definition for the __mul__ method and it just looked like the wrong approach anyway.

So is it possible to define a symmetric function that behaves like this inside the user interface?

Alternatively, it would be nice if there was an argument to the built-in function() to specify the symmetry,

s = function('s', nargs=2, sym='symmetric')

Defining a symmetric function

I am new to Sage (about a week) and Updated question:

I would like to define a generic symbolic function called s that doesn't evaluate to anything, but it has to be whose arguments are totally symmetric.

So if I type s(3,2) the output must be s(2,3), or typing s(1,4,3,2) the output must be s(1,2,3,4) etc.

   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? I am searching the documentation to try to implement this, but so far no luck.

I tried using the function sort_subscript()* that I found in the tensor.pdf documentation, but the attempt below obviously fails in an infinite loop:

def s(*m):
    a=sort_subscript(m);
    return s(a[1]);

How can I implement this? My motivation is that s(i,j) are the symmetric Mandelstam invariants in a scattering amplitude context.

Edit:

Today I tried this:

class s(BuiltinFunction):
    def __init__(self, x1, x2):
        if x2 >= x1:
            self.x = x1
            self.y = x2
            BuiltinFunction.__init__(self,'s(%s,%s)' % (x1,x2))
         else:
             self.x = x2
             self.y = x1
             BuiltinFunction.__init__(self,'s(%s,%s)' % (x2,x1))

And it works in the sense that

   sage: s(4,2) 
   s(2,4)

However, this is not complete since

sage: 2*s(4,2)
...
TypeError: unsupported operand parent(s) for '*': 'Integer Ring' and '<class '__main__.s'>'

where I would expect the answer 2*s(2,4). So it is not so simple and I couldn't get a working definition for the __mul__ method and it just looked like the wrong approach anyway.

So is it possible to define a symmetric function that behaves like this inside the user interface?

Alternatively, it It would be nice if there was an argument to the built-in function() to specify the symmetry,symmetry of its arguments. In this case I would get what I want with something like

s = function('s', nargs=2, sym='symmetric')

Partial 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

def symmetric(self, x1,x2):
    if x1 < x2:
        pass
    else:
        return self(x2,x1)

and use it together with 'eval_func'

 s = function("s", eval_func=symmetric)

Doing this works in the special case when the function contains two arguments:

  sage: 2*s(2,1)*s(6,5)^2
  2*s(5, 6)^2*s(1, 2)

So the question now becomes: how can I extend this definition to a function with an arbitrary number of arguments?

Defining a symmetric function

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 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

def symmetric(self, x1,x2):
    if x1 < x2:
        pass
    else:
        return self(x2,x1)

and use it together with 'eval_func'

 s = function("s", eval_func=symmetric)

Doing this works in the special case when the function contains two arguments:

  sage: 2*s(2,1)*s(6,5)^2
  2*s(5, 6)^2*s(1, 2)

So the question now becomes: how can I extend this definition to a function with an arbitrary number of arguments?

Defining a generic symbolic function with symmetric functionarguments

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 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

def symmetric(self, x1,x2):
    if x1 < x2:
        pass
    else:
        return self(x2,x1)

and use it together with 'eval_func'

 s = function("s", eval_func=symmetric)

Doing this works in the special case when the function contains two arguments:

  sage: 2*s(2,1)*s(6,5)^2
  2*s(5, 6)^2*s(1, 2)

So the 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:
    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])
    else:
    # doesn't work
        return self(x)

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).

Defining a generic symbolic function with symmetric arguments

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 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

def symmetric(self, x1,x2):
    if x1 < x2:
        pass
    else:
        return self(x2,x1)

and use it together with 'eval_func'

 s = function("s", eval_func=symmetric)

Doing this works in the special case when the function contains two arguments:

  sage: 2*s(2,1)*s(6,5)^2
  2*s(5, 6)^2*s(1, 2)

So the 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:
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])
    else:
    # doesn't work
        return self(x)

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).

Defining a generic symbolic function with symmetric arguments

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!