SymPy中表达式的抽象表示

3
考虑这两个方程式:
x^y + xy
a^b + ab
我希望能够将它们识别为相同的符号表达式。 "Simplify" 并不能解决问题。 "Subs"(替换 a 为 x 等)也不总是适用,因为变量的顺序可能会改变。
那么,有没有一种方法可以获得与使用的符号无关的 SymPy 表达式的抽象表示呢?
2个回答

4
一个不与使用的符号相关联的表示称为函数。例如,

f1 = lambda x, y: (2*x+y)**2 

定义了一个与x和y无关的函数,它们只是该函数内部的占位符。 (这是一个Python函数;也可以定义SymPy Function对象,但在此处并不重要。)

如果有人问你(2*x+y)**2是否与a**2 + 4*b*(a+b) "相同",你会怎么做?我知道的唯一方法是简化两个表达式,并尝试在所有可能的排列下匹配变量。这就是以下代码所做的事情。

from sympy import *
from itertools import permutations
f1 = lambda x, y: (2*x+y)**2
f2 = lambda a, b: a**2 + 4*b*(a+b)
vars = symbols("v0:2")    # auxiliary variables to plug in f1 and f2
identical = any([simplify(f1(*vars) - f2(*p)) == 0 for p in permutations(vars)])

现在,由于你所描述的表达式相同,identical为真。如果你有表达式而不是函数,那么可以使用subs来代替:
x, y, a, b = symbols("x y a b")
expr1 = (2*x+y)**2
expr2 = a**2 + 4*b*(a+b)
vars = symbols("v0:2")
identical = any([simplify(expr1.subs(zip((x, y), vars)) - expr2.subs(zip((a, b), p))) for p in permutations(vars)]) 

0

稍微解释一下:

我对排列方法并不太满意。所以,我继续深入研究,发现SymPy生成一棵树形图来表示符号表达式。树的结构是表达式的结构,与符号无关。然而,一旦你有了相应的图形,你就需要决定它们是否同构(即两个表达式是否相同),这是一个非常复杂的问题


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接