# sympy/sympy

### Subversion checkout URL

You can clone with
or
.

1400: cse is deterministic and ignores singleton expressions

```deterministic

Since cse relies on making substitutions at the very beginning
in the preprocessing, and substitution is an order-sensitive proceedure,
it was necessary to sort the Adds that are being identified in that
process.

The use of default_sort_key from the traversal was removed. This is not
needed in the sub-expression identification stage. The insert method
that sought to keep the expressions in order was also removed. The
default_sort_key applied in one branch of the expression tree in one
of the expressions given to cse doesn't guarantee that another expression
with the same key (as was defined in the insert method) will be in a
deterministic order -- the tie would not be broken.

So now all the expressions are collected however they come from the
tree and are assembled in set. These (and the Add and Mul terms that
are handled individually) are sorted with the lazyDSU sort which seeks
to put the items in some canonical order. This is the source, then,
of determinism in the method.

In addition, expressions that are only used once are no longer reported
in the returned expressions, e.g. whereas one might have gotten
[[(x0, x+1)], [cos(x0)]] perviously, now [[], [cos(x + 1)]] will be
returned.

The insert method used to keep the expressions arranged in a particular
order was removed since more than this is```
commit 33fa7f8d933678f27b82f6fcb1ea816846910cdc 1 parent 88a1348
smichr authored
7 doc/src/modules/rewriting.rst
 @@ -64,7 +64,8 @@ Common Subexpression Detection and Collection .. module:: sympy.simplify.cse_main Before evaluating a large expression, it is often useful to identify common -subexpressions, collect them and evaluate them at once. This is implemented in the ``cse`` function. Examples:: +subexpressions, collect them and evaluate them at once. This is implemented +in the ``cse`` function. Examples:: >>> from sympy import cse, sqrt, sin, pprint >>> from sympy.abc import x @@ -79,8 +80,8 @@ subexpressions, collect them and evaluate them at once. This is implemented in t >>> pprint(cse(sqrt(sin(x+1) + 5 + cos(y))*sqrt(sin(x+1) + 4 + cos(y))), ... use_unicode=True) - ⎛ ⎡ ________ ________⎤⎞ - ⎝[(x₀, cos(y)), (x₁, sin(x + 1)), (x₂, x₀ + x₁)], ⎣╲╱ x₂ + 4 ⋅╲╱ x₂ + 5 ⎦⎠ + ⎛ ⎡ ________ ________⎤⎞ + ⎝[(x₀, sin(x + 1) + cos(y))], ⎣╲╱ x₀ + 4 ⋅╲╱ x₀ + 5 ⎦⎠ >>> pprint(cse((x-y)*(z-y) + sqrt((x-y)*(z-y))), use_unicode=True) ⎛ ⎡ ____ ⎤⎞
25 sympy/core/tests/test_expand.py
 @@ -100,25 +100,18 @@ def test_expand_frac(): def test_issue_3022(): + # TODO when 3460 is merged, move this import to the top from sympy import cse - ans = S('''([ - (x0, im(x)), - (x1, re(x)), - (x2, atan2(x0, x1)/2), - (x3, sin(x2)), (x4, cos(x2)), - (x5, x0**2 + x1**2), - (x6, atan2(0, x5)/4), - (x7, cos(x6)), - (x8, sin(x6)), - (x9, x4*x7), - (x10, x4*x8), - (x11, x3*x8), - (x12, x3*x7)], - [sqrt(2)*(x10 + I*x10 + x11 - I*x11 + x12 + I*x12 - x9 + I*x9)/ - (8*pi**(3/2)*x5**(1/4))])''') eq = -I*exp(-3*I*pi/4)/(4*pi**(S(3)/2)*sqrt(x)) r, e = cse((eq).expand(complex=True)) - assert abs((eq - e[0].subs(reversed(r))).subs(x, 1 + 3*I)) < 1e-9 + assert r == S('''[ + (x0, re(x)), (x1, im(x)), (x2, atan2(x1, x0)/2), (x3, x0**2 + x1**2), + (x4, sin(x2)), (x5, cos(x2)), (x6, atan2(0, x3)/4), (x7, sin(x6)), + (x8, cos(x6)), (x9, x4*x7), (x10, x5*x7), (x11, x4*x8), (x12, x5*x8) + ]''') + assert e == S('''[ + sqrt(2)*(x10 + I*x10 + x11 + I*x11 - x12 + I*x12 + x9 - + I*x9)/(8*pi**(S(3)/2)*x3**(S(1)/4))]''') def test_expand_power_base():
147 sympy/simplify/cse_main.py