Python - Sympy在evaluate=False时表达式相等检查的问题

2 投票
3 回答
737 浏览
提问于 2025-04-17 06:02

在我的项目中,当我创建任何 AddMul 对象时,我必须使用 evaluate=false。这样做的时候,我在比较这些对象是否相等时遇到了问题。问题出在参数的顺序上。

请看下面的例子:

k2=Mul(*[x,y,2],evaluate=False)
k1=Mul(*[x,2,y],evaluate=False)
print k1==k2 

结果是 false,因为 k2.args(x,y,2),而 k1.args(x,2,y)。所以,当比较这两个元组是否相等时,它返回 false

有没有办法让我得到想要的结果呢?

另外,如果我对元组进行一些操作(比如反转顺序再检查),在 k1k2 是由不同的 Mul 对象组成的情况下,这种方法也会失败(比如 k1.args = 2*x,yk2.args = 2*y,x)。

我不能在这里使用排序,因为在这种情况下 Add([x+y,z],evaluate=False)Add([x+z,y],evaluate=False) 将会是两个不同的表达式。而且如果我使用 evaluate=True,在这种情况下 Add([x+y],x])Add([2*x+y]) 会被认为是相同的,这不是我想要的。

3 个回答

0

这段内容对你有帮助吗?

print simplify(k1 - k2) == 0 # True
print k1 == k2 # Still False
1

Mul不知道x和y都是标量(就是普通的数字)。矩阵相乘是有顺序的,所以在你的例子中,k1和k2不一定是相等的。如果你在程序中确定x和y总是标量(或者其他一些乘法是可以交换和结合的值),那么可能有办法把每个项中的常量提取出来,比较这些常量,然后比较一个排序后的项列表。

0

找到了一种解决方法。

在加法/乘法的类里,在形成表达式的时候,使用下面的代码把所有的参数都整理成一行:

   flatten_args = []
            for arg in args:
                if (arg.__class__==cls):
                    flatten_args.extend(arg.args)
                else:
                    flatten_args.append(arg)

            obj = Expr.__new__(cls, *flatten_args) 

在进行相等性检查的时候,我多加了一步,先把参数列表排序,使用 arg_list.sort(),然后再比较这两个列表。

撰写回答