Reputation: 3020
In my project I have to use evaluate=false
at the time when i am creating any Add
or Mul
objects. In this case I am facing a problem when I apply equality checks on these objects. The issue is because of the ordering of the arguments.
Please consider the example below:
k2=Mul(*[x,y,2],evaluate=False)
k1=Mul(*[x,2,y],evaluate=False)
print k1==k2
The result is false
as k2.args
are (x,y,2)
and k1.args
are (x,2,y)
.
So, while the comparison checks for tuple equality it returns false
.
Is there any way I can get the wanted result?
Also, if I put some operation on tuples (like reversing the order and then checking), it fails in the cases when k1
and k2
are formed from different Mul
objects (like when k1.args
= 2*x,y
and k2.args
= 2*y,x
)
I can't use sorting here , as in this case Add([x+y,z],evaluate=False)
and Add([x+z,y],evaluate=False)
will be two different expressions. Also if i use evalaute=True
, in this case Add([x+y],x])
and Add([2*x+y])
will be the same, which i don't want.
Upvotes: 2
Views: 772
Reputation: 3020
Found one work around.
in Add/Mul classes at the expression formation flatten all arguments using below code
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)
and at the time of equality check ,i am putting one extra check
sort the args list first arg_list.sort()
and than compare two lists
Upvotes: 0
Reputation: 14440
Does the following help you?
print simplify(k1 - k2) == 0 # True
print k1 == k2 # Still False
Upvotes: 0
Reputation: 790
Mul doesn't know that x and y both represent scalars. Matrix multiplication depends on the order of the arguments so in your example k1 and k2 are not necessarily equal. If you know that in your program x and y will always be scalars (or some other type of value where multiplication is commutative and associative) there may be a way to factor out the constants from each term, compare the constants and compare a sorted list of terms.
Upvotes: 1