【问题标题】:Abstract representation of expressions in SymPySymPy 中表达式的抽象表示
【发布时间】:2017-05-30 22:31:01
【问题描述】:

考虑这两个等式:

x^y + xy

a^b + ab

我希望能够将它们识别为相同的符号表达式。 “简化”是行不通的。 “Subs”(用 a 代替 x 等)也不会总是有效,因为变量的顺序可能会改变等。

那么,有没有办法为 SymPy 表达式获取独立于所用符号的抽象表示?

【问题讨论】:

    标签: python sympy


    【解决方案1】:

    与所使用的符号无关的表示是函数。例如,

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

    【讨论】:

      【解决方案2】:

      稍微详细说明一下:

      我对排列方法不太满意。所以,我一直在挖掘,我注意到 SymPy 生成了一个树形图来表示符号表达式。树的结构就是表达式的结构,它独立于符号。但是,一旦有了相应的图,就需要确定它们是否同构(即两个表达式是否相同),即very non-trivial problem

      【讨论】:

        猜你喜欢
        • 2015-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-11
        • 2011-05-05
        • 1970-01-01
        • 1970-01-01
        • 2017-05-31
        相关资源
        最近更新 更多