Skip to content

Commit

Permalink
Merge pull request #12232 from mohit3011/Fixes#12230
Browse files Browse the repository at this point in the history
Adding UnevaluatedExpr() Tutorial
  • Loading branch information
Upabjojr committed Mar 2, 2017
2 parents d604979 + 9a52759 commit b0cd981
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
5 changes: 5 additions & 0 deletions doc/src/modules/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ Expr
.. autoclass:: Expr
:members:

UnevaluatedExpr
---------------
.. autoclass:: UnevaluatedExpr
:members:

AtomicExpr
----------
.. autoclass:: AtomicExpr
Expand Down
97 changes: 97 additions & 0 deletions doc/src/tutorial/manipulation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,103 @@ traversals easy. We could have also written our algorithm as
x
y


Prevent expression evaluation
=============================

There are generally two ways to prevent the evaluation, either pass an
``evaluate=False`` parameter while constructing the expression, or create
an evaluation stopper by wrapping the expression with ``UnevaluatedExpr``.

For example:

>>> from sympy import Add
>>> from sympy.abc import x, y, z
>>> x + x
2*x
>>> Add(x, x)
2*x
>>> Add(x, x, evaluate=False)
x + x

If you don't remember the class corresponding to the expression you
want to build (operator overloading usually assumes ``evaluate=True``),
just use ``sympify`` and pass a string:

>>> from sympy import sympify
>>> sympify("x + x", evaluate=False)
x + x

Note that ``evaluate=False`` won't prevent future evaluation in later
usages of the expression:

>>> expr = Add(x, x, evaluate=False)
>>> expr
x + x
>>> expr + x
3*x

That's why the class ``UnevaluatedExpr`` comes handy.
``UnevaluatedExpr`` is a method provided by SymPy which lets the user keep
an expression unevaluated. By *unevaluated* it is meant that the value
inside of it will not interact with the expressions outside of it to give
simplified outputs. For example:

>>> from sympy import UnevaluatedExpr
>>> expr = x + UnevaluatedExpr(x)
>>> expr
x + x
>>> x + expr
2*x + x

The `x` remaining alone is the `x` wrapped by ``UnevaluatedExpr``.
To release it:

>>> (x + expr).doit()
3*x

Other examples:

>>> from sympy import *
>>> from sympy.abc import x, y, z
>>> uexpr = UnevaluatedExpr(S.One*5/7)*UnevaluatedExpr(S.One*3/4)
>>> uexpr
(5/7)*(3/4)
>>> x*UnevaluatedExpr(1/x)
x*1/x

A point to be noted is that ``UnevaluatedExpr`` cannot prevent the
evaluation of an expression which is given as argument. For example:

>>> expr1 = UnevaluatedExpr(x + x)
>>> expr1
2*x
>>> expr2 = sympify('x + x', evaluate=False)
>>> expr2
x + x

Remember that ``expr2`` will be evaluated if included into another
expression. Combine both of the methods to prevent both inside and outside
evaluations:

>>> UnevaluatedExpr(sympify("x + x", evaluate=False)) + y
y + x + x

``UnevalutedExpr`` is supported by SymPy printers and can be used to print the
result in different output forms. For example

>>> from sympy import latex
>>> uexpr = UnevaluatedExpr(S.One*5/7)*UnevaluatedExpr(S.One*3/4)
>>> print(latex(uexpr))
\frac{5}{7} \frac{3}{4}

In order to release the expression and get the evaluated LaTeX form,
just use ``.doit()``:

>>> print(latex(uexpr.doit()))
\frac{15}{28}


.. rubric:: Footnotes

.. [#symbols-fn] We have been using ``symbols`` instead of ``Symbol`` because it
Expand Down

0 comments on commit b0cd981

Please sign in to comment.