Is there a way to recursively pass flags through the subexpressions?

40 views
Skip to first unread message

Robert Lee

unread,
Oct 7, 2016, 3:31:30 PM10/7/16
to sympy
I want the ability to be able to recursively pass flags like evaluate=False through all the sub-expressions. Is this currently possible? The best hack I have is actually going through and reforming each sub-expression recursively and setting the appropriate flags.


Aaron Meurer

unread,
Oct 7, 2016, 4:17:14 PM10/7/16
to sy...@googlegroups.com
You can use with evaluate(False):

In [11]: with evaluate(False):
....: print(x - sin(x - x))
....:
x - sin(-x + x)

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at https://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/2a4ab16d-7eef-42e7-94ec-bad9c62aadf3%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Robert Lee

unread,
Oct 10, 2016, 1:58:21 PM10/10/16
to sympy
Thanks Aaron. The evaluate context is incredibly useful...

Another interesting I've noted is that equality checking of expressions (using == operator, not equals) seem to fail if one subexpression has evaluate set to False whereas an identical expression has the same subexpression set to True. Is this by design -- for more complicated core types -- or a bug?

Here's some sample code to reproduce the issue:

>>> expr_eval_false = sympify('2*x-4', evaluate=False)

>>> expr_eval_false

2*x - 4

>>> expr_eval_true = sympify('2*x-4', evaluate=True)

>>> expr_eval_false == expr_eval_true

False

>>> expr_eval_false.equals(expr_eval_true)

True


I'm interested in comparing sympy expression trees so look forward to some independent work in that area.

Aaron Meurer

unread,
Oct 10, 2016, 2:03:27 PM10/10/16
to sy...@googlegroups.com
== does exact structural equality checking. a == b is basically the
same as

a.func == b.func and a.args == b.args.

The issue here is that Add sorts its arguments (so that x + y == y + x
gives True), but when evaluate=False is used, the sorting is bypassed:

In [2]: sympify('2*x-4', evaluate=False).args
Out[2]: (2⋅x, -4)

In [3]: (2*x - 4).args
Out[3]: (-4, 2⋅x)

The same issue would occur with Mul.

Aaron Meurer
> https://groups.google.com/d/msgid/sympy/04053b81-d139-49a1-9b27-43f88b594be7%40googlegroups.com.

Robert Lee

unread,
Mar 1, 2017, 4:10:44 PM3/1/17
to sympy
Following up on this conversation, has anyone given any thought on an efficient way to check for structural equality for evaluate=False expressions? This is my current implementation but I'd be curious if there is a niftier way to check instead of manually recursing through like I've done:

https://gist.github.com/leerobert/e8a65492b6e70e92997510dc0f1debf3

Also is there a way we could potentially add in a check to override the __eq__ function for Basic when within the evaluate=False context?
Reply all
Reply to author
Forward
0 new messages