在Python中定义一个抽象的交换函数(SymPy)

时间:2017-07-19 08:24:58

标签: python sympy

假设我定义了一个函数H

from sympy import Function
H = Function('H')

我如何在其参数中使H可交换为

>>> H(x,y)+H(y,x)
2*H(x,y)

其中xy是符号。

我目前的解决方法是定义一个额外的函数H1,它通过首先对参数进行排序来返回H(x,y)。然后Python完成剩下的工作:

>>> H1(x,y)+H1(y,x)
2*H(x,y)

1 个答案:

答案 0 :(得分:0)

您可以定义SymPy Function类的扩展名以添加此属性,类似于示例here

class H(sympy.Function):
    nargs = (2,)

    @classmethod
    def eval(cls, arg1, arg2):
        if order(arg1,arg2):
            return H(arg2,arg1)

如果order(arg1,arg2)True,则会交换参数,否则会保留原样。这样,如果使用相同但交换的参数调用H,则输出应始终相同。

现在,我们只需要一个好的order功能。最简单的方法是将相应的符号转换为字符串并进行比较:

order = lambda arg1,arg2: str(arg1)>str(arg2)

但是,如果参数等效但在符号表示中不相同,则可能无法按预期工作。以下是order的更复杂版本,它通过使用SymPy的equals(在使用简化时比==更彻底)将此考虑在内(尽可能):

def order(arg1,arg2):
    if arg1.equals(arg2):
        return False
    else:
        return str(arg1)>str(arg2)

请注意,order会经常执行,因此可能需要保持快速和简单。

函数H现在具有您想要的属性:

from sympy.abc import a,b
print( H(a,b) + H(b,a) )
# 2*H(a, b)