Python - Sympy在evaluate=False时表达式相等检查的问题
在我的项目中,当我创建任何 Add
或 Mul
对象时,我必须使用 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
。
有没有办法让我得到想要的结果呢?
另外,如果我对元组进行一些操作(比如反转顺序再检查),在 k1
和 k2
是由不同的 Mul
对象组成的情况下,这种方法也会失败(比如 k1.args
= 2*x,y
和 k2.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()
,然后再比较这两个列表。