Simplify

simplify

sympy.simplify.simplify.simplify(expr)

Naively simplifies the given expression.

Simplification is not a well defined term and the exact strategies this function tries can change in the future versions of SymPy. If your algorithm relies on “simplification” (whatever it is), try to determine what you need exactly - is it powsimp()?, radsimp()?, together()?, logcombine()?, or something else? And use this particular function directly, because those are well defined and thus your algorithm will be robust.

collect

sympy.simplify.simplify.collect(expr, syms, evaluate=True, exact=False)

Collect additive terms with respect to a list of symbols up to powers with rational exponents. By the term symbol here are meant arbitrary expressions, which can contain powers, products, sums etc. In other words symbol is a pattern which will be searched for in the expression’s terms.

This function will not apply any redundant expanding to the input expression, so user is assumed to enter expression in final form. This makes ‘collect’ more predictable as there is no magic behind the scenes. However it is important to note, that powers of products are converted to products of powers using ‘separate’ function.

There are two possible types of output. First, if ‘evaluate’ flag is set, this function will return a single expression or else it will return a dictionary with separated symbols up to rational powers as keys and collected sub-expressions as values respectively.

>>> from sympy import collect, sympify
>>> from sympy.abc import a, b, c, x, y, z

This function can collect symbolic coefficients in polynomial or rational expressions. It will manage to find all integer or rational powers of collection variable:

>>> collect(a*x**2 + b*x**2 + a*x - b*x + c, x)
c + x*(a - b) + x**2*(a + b)

The same result can be achieved in dictionary form:

>>> d = collect(a*x**2 + b*x**2 + a*x - b*x + c, x, evaluate=False)
>>> d[x**2]
a + b
>>> d[x]
a - b
>>> d[sympify(1)]
c

You can also work with multi-variate polynomials. However remember that this function is greedy so it will care only about a single symbol at time, in specification order:

>>> collect(x**2 + y*x**2 + x*y + y + a*y, [x, y])
x*y + y*(1 + a) + x**2*(1 + y)

Also more complicated expressions can be used as patterns:

>>> from sympy import sin, log
>>> collect(a*sin(2*x) + b*sin(2*x), sin(2*x))
(a + b)*sin(2*x)
>>> collect(a*x*log(x) + b*(x*log(x)), x*log(x))
x*(a + b)*log(x)

It is also possible to work with symbolic powers, although it has more complicated behavior, because in this case power’s base and symbolic part of the exponent are treated as a single symbol:

>>> collect(a*x**c + b*x**c, x)
a*x**c + b*x**c
>>> collect(a*x**c + b*x**c, x**c)
x**c*(a + b)

However if you incorporate rationals to the exponents, then you will get well known behavior:

>>> collect(a*x**(2*c) + b*x**(2*c), x**c)
(x**2)**c*(a + b)

Note also that all previously stated facts about ‘collect’ function apply to the exponential function, so you can get:

>>> from sympy import exp
>>> collect(a*exp(2*x) + b*exp(2*x), exp(x))
(a + b)*exp(2*x)

If you are interested only in collecting specific powers of some symbols then set ‘exact’ flag in arguments:

>>> collect(a*x**7 + b*x**7, x, exact=True)
a*x**7 + b*x**7
>>> collect(a*x**7 + b*x**7, x**7, exact=True)
x**7*(a + b)

You can also apply this function to differential equations, where derivatives of arbitrary order can be collected. Note that if you collect with respect to a function or a derivative of a function, all derivatives of that function will also be collected. Use exact=True to prevent this from happening:

>>> from sympy import Derivative as D, collect, Function
>>> f = Function('f') (x)
>>> collect(a*D(f,x) + b*D(f,x), D(f,x))
(a + b)*D(f(x), x)
>>> collect(a*D(D(f,x),x) + b*D(D(f,x),x), f)
(a + b)*D(f(x), x, x)
>>> collect(a*D(D(f,x),x) + b*D(D(f,x),x), D(f,x), exact=True)
a*D(f(x), x, x) + b*D(f(x), x, x)
>>> collect(a*D(f,x) + b*D(f,x) + a*f + b*f, f,x)
(a + b)*D(f(x), x) + (a + b)*f(x)

Or you can even match both derivative order and exponent at time:

>>> collect(a*D(D(f,x),x)**2 + b*D(D(f,x),x)**2, D(f,x))

D(f(x), x, x)**2*(a + b)

== Notes ==
  • arguments are expected to be in expanded form, so you might have to call expand() prior to calling this function.

separate

sympy.simplify.simplify.separate(expr, deep=False)

Rewrite or separate a power of product to a product of powers but without any expanding, i.e., rewriting products to summations.

>>> from sympy.abc import x, y, z
>>> from sympy import separate, sin, cos, exp
>>> separate((x*y)**2)
x**2*y**2
>>> separate((x*(y*z)**3)**2)
x**2*y**6*z**6
>>> separate((x*sin(x))**y + (x*cos(x))**y)
x**y*cos(x)**y + x**y*sin(x)**y
>>> separate((exp(x)*exp(y))**x)
exp(x**2)*exp(x*y)
>>> separate((sin(x)*cos(x))**y)
cos(x)**y*sin(x)**y

Notice that summations are left untouched. If this is not the requested behavior, apply ‘expand’ to input expression before:

>>> separate(((x+y)*z)**2)
z**2*(x + y)**2
>>> separate((x*y)**(1+z))
x**(1 + z)*y**(1 + z)

together

sympy.simplify.simplify.together(expr, deep=False)

Combine together and denest rational functions into a single fraction. By default the resulting expression is simplified to reduce the total order of both numerator and denominator and minimize the number of terms.

Denesting is done recursively on the fractions level. However this function will not attempt to rewrite the interior of composite objects, like functions, unless ‘deep’ is True.

By definition, ‘together’ is a complement to ‘apart’, so apart(together(expr)) should return expr unchanged.

>>> from sympy.abc import x, y, z
>>> from sympy import together

You can work with sums of fractions easily. The algorithm used here will, in an iterative style, collect numerators and denominator of all expressions involved and perform needed simplifications:

>>> together(1/x + 1/y)
(x + y)/(x*y)
>>> together(1/x + 1/y + 1/z)
(x*y + x*z + y*z)/(x*y*z)
>>> together(1/(x*y) + 1/y**2)
(x + y)/(x*y**2)

Or you can just denest multi-level fractional expressions:

>>> together(1/(1 + 1/x))
x/(1 + x)

together() can also work perfectly well with symbolic powers and/or exponential functions:

>>> together(1/x**y + 1/x**(y-1))
x**(-y)*(1 + x)

#>>> together(1/x**(2*y) + 1/x**(y-z)) #x**(-2*y)*(1 + x**(y + z))

#>>> together(1/exp(x) + 1/(x*exp(x))) #(1+x)/(x*exp(x))

#>>> together(1/exp(2*x) + 1/(x*exp(3*x))) #(1+exp(x)*x)/(x*exp(3*x))

radsimp

sympy.simplify.simplify.radsimp(expr)

Rationalize the denominator.

Examples:
>>> from sympy import radsimp, sqrt, Symbol
>>> radsimp(1/(2+sqrt(2)))
1 - 2**(1/2)/2
>>> x,y = map(Symbol, 'xy')
>>> e = ((2+2*sqrt(2))*x+(2+sqrt(8))*y)/(2+sqrt(2))
>>> radsimp(e)
x*2**(1/2) + y*2**(1/2)

ratsimp

sympy.simplify.simplify.ratsimp(expr)
== Usage ==
ratsimp(expr) -> joins two rational expressions and returns the simples form
== Notes ==
Currently can simplify only simple expressions, for this to be really useful multivariate polynomial algorithms are needed
== Examples ==
>>> from sympy import ratsimp
>>> from sympy.abc import x, y
>>> ratsimp(1/x + 1/y)
(x + y)/(x*y)

fraction

sympy.simplify.simplify.fraction(expr, exact=False)

Returns a pair with expression’s numerator and denominator. If the given expression is not a fraction then this function will assume that the denominator is equal to one.

This function will not make any attempt to simplify nested fractions or to do any term rewriting at all.

If only one of the numerator/denominator pair is needed then use numer(expr) or denom(expr) functions respectively.

>>> from sympy import fraction, Rational, Symbol
>>> from sympy.abc import x, y
>>> fraction(x/y)
(x, y)
>>> fraction(x)
(x, 1)
>>> fraction(1/y**2)
(1, y**2)
>>> fraction(x*y/2)
(x*y, 2)
>>> fraction(Rational(1, 2))
(1, 2)

This function will also work fine with assumptions:

>>> k = Symbol('k', negative=True)
>>> fraction(x * y**k)
(x, y**(-k))

If we know nothing about sign of some exponent and ‘exact’ flag is unset, then structure this exponent’s structure will be analyzed and pretty fraction will be returned:

>>> from sympy import exp
>>> fraction(2*x**(-y))
(2, x**y)

#>>> fraction(exp(-x)) #(1, exp(x))

>>> fraction(exp(-x), exact=True)
(exp(-x), 1)

trigsimp

sympy.simplify.simplify.trigsimp(expr, deep=False, recursive=False)

== Usage ==

trigsimp(expr) -> reduces expression by using known trig identities

== Notes ==

deep: - Apply trigsimp inside functions recursive: - Use common subexpression elimination (cse()) and apply trigsimp recursively (recursively==True is quite expensive operation if the expression is large)

== Examples ==
>>> from sympy import trigsimp, sin, cos, log
>>> from sympy.abc import x, y
>>> e = 2*sin(x)**2 + 2*cos(x)**2
>>> trigsimp(e)
2
>>> trigsimp(log(e))
log(2*cos(x)**2 + 2*sin(x)**2)
>>> trigsimp(log(e), deep=True)
log(2)

powsimp

sympy.simplify.simplify.powsimp(expr, deep=False, combine='all')
== Usage ==
powsimp(expr, deep) -> reduces expression by combining powers with similar bases and exponents.
== Notes ==

If deep is True then powsimp() will also simplify arguments of functions. By default deep is set to False. You can make powsimp() only combine bases or only combine exponents by changing combine=’base’ or combine=’exp’. By default, combine=’all’, which does both. combine=’base’ will only combine:

 a   a          a                          2x      x
x * y  =>  (x*y)   as well as things like 2   =>  4

and combine=’exp’ will only combine

 a   b      (a + b)
x * x  =>  x

combine=’exp’ will strictly only combine exponents in the way that used to be automatic. Also use deep=True if you need the old behavior.

When combine=’all’, ‘exp’ is evaluated first. Consider the first example below for when there could be an ambiguity relating to this. This is done so things like the second example can be completely combined. If you want ‘base’ combined first, do something like powsimp(powsimp(expr, combine=’base’), combine=’exp’).

== Examples ==
>>> from sympy import powsimp, exp, log
>>> from sympy.abc import x, y, z, n
>>> powsimp(x**y*x**z*y**z, combine='all')
x**(y + z)*y**z
>>> powsimp(x**y*x**z*y**z, combine='exp')
x**(y + z)*y**z
>>> powsimp(x**y*x**z*y**z, combine='base')
x**y*(x*y)**z
>>> powsimp(x**z*x**y*n**z*n**y, combine='all')
(n*x)**(y + z)
>>> powsimp(x**z*x**y*n**z*n**y, combine='exp')
n**(y + z)*x**(y + z)
>>> powsimp(x**z*x**y*n**z*n**y, combine='base')
(n*x)**y*(n*x)**z
>>> powsimp(log(exp(x)*exp(y)))
log(exp(x)*exp(y))
>>> powsimp(log(exp(x)*exp(y)), deep=True)
x + y

combsimp

sympy.simplify.simplify.combsimp(expr)

hypersimp

sympy.simplify.simplify.hypersimp(f, k)

Given combinatorial term f(k) simplify its consecutive term ratio i.e. f(k+1)/f(k). The input term can be composed of functions and integer sequences which have equivalent representation in terms of gamma special function.

The algorithm performs three basic steps:

  1. Rewrite all functions in terms of gamma, if possible.
  2. Rewrite all occurrences of gamma in terms of products of gamma and rising factorial with integer, absolute constant exponent.
  3. Perform simplification of nested fractions, powers and if the resulting expression is a quotient of polynomials, reduce their total degree.

If f(k) is hypergeometric then as result we arrive with a quotient of polynomials of minimal degree. Otherwise None is returned.

For more information on the implemented algorithm refer to:

[1] W. Koepf, Algorithms for m-fold Hypergeometric Summation,
Journal of Symbolic Computation (1995) 20, 399-417

hypersimilar

sympy.simplify.simplify.hypersimilar(f, g, k)

Returns True if ‘f’ and ‘g’ are hyper-similar.

Similarity in hypergeometric sense means that a quotient of f(k) and g(k) is a rational function in k. This procedure is useful in solving recurrence relations.

For more information see hypersimp().

nsimplify

sympy.simplify.simplify.nsimplify(expr, constants=[], tolerance=None, full=False)

Numerical simplification – tries to find a simple formula that numerically matches the given expression. The input should be possible to evalf to a precision of at least 30 digits.

Optionally, a list of (rationally independent) constants to include in the formula may be given.

A lower tolerance may be set to find less exact matches.

With full=True, a more extensive search is performed (this is useful to find simpler numbers when the tolerance is set low).

Examples:

>>> from sympy import nsimplify, sqrt, GoldenRatio, exp, I, exp, pi
>>> nsimplify(4/(1+sqrt(5)), [GoldenRatio])
-2 + 2*GoldenRatio
>>> nsimplify((1/(exp(3*pi*I/5)+1)))
1/2 - I*(1/4 + 5**(1/2)/10)**(1/2)
>>> nsimplify(I**I, [pi])
exp(-pi/2)
>>> nsimplify(pi, tolerance=0.01)
22/7

Rewrite

cancel

sympy.simplify.rewrite.cancel(expr, *args, **kwargs)

Cancel common factors in a given rational function.

Given a quotient of polynomials, performing only gcd and quo operations in polynomial algebra, return rational function with numerator and denominator of minimal total degree in an expanded form.

For all other kinds of expressions the input is returned in an unchanged form. Note however, that ‘cancel’ function can thread over sums and relational operators.

Additionally you can specify a list of variables to perform cancellation more efficiently using only those symbols.

>>> from sympy import cancel, sqrt
>>> from sympy.abc import x, y
>>> cancel((x**2-1)/(x-1))
1 + x
>>> cancel((x**2-y**2)/(x-y), x)
x + y
>>> cancel((x**2-2)/(x+sqrt(2)))
x - 2**(1/2)

trim

sympy.simplify.rewrite.trim(f, *symbols, **flags)

Cancel common factors in a given formal rational expression.

Given an arbitrary expression, map all functional components to temporary symbols, rewriting this expression to rational function form and perform cancellation of common factors.

When given a rational function or a list of symbols discards all functional components, then this procedure is equivalent to cancel().

Note that this procedure can thread over composite objects like big operators, matrices, relational operators etc. It can be also called recursively (to change this behavior unset ‘recursive’ flag).

>>> from sympy import Function, trim, sin
>>> from sympy.abc import x, y
>>> f = Function('f')
>>> trim((f(x)**2+f(x))/f(x))
1 + f(x)
>>> trim((x**2+x)/x)
1 + x

Recursively simplify expressions:

>>> trim(sin((f(x)**2+f(x))/f(x)))
sin(1 + f(x))

apart

sympy.simplify.rewrite.apart(expr, *args, **kwargs)

Compute partial fraction decomposition of a rational function.

Given a rational function ‘f’, performing only gcd operations over the algebraic closure of the initial field of definition, compute full partial fraction decomposition with fractions having linear denominators.

For all other kinds of expressions the input is returned in an unchanged form. Note however, that ‘apart’ function can thread over sums and relational operators.

Note that no factorization of the initial denominator of ‘f’ is needed. The final decomposition is formed in terms of a sum of RootSum instances. By default RootSum tries to compute all its roots to simplify itself. This behavior can be however avoided by setting the keyword flag evaluate=False, which will make this function return a formal decomposition.

>>> from sympy import apart
>>> from sympy.abc import x, y
>>> apart(y/(x+2)/(x+1), x)
y/(1 + x) - y/(2 + x)
>>> apart(1/(1+x**5), x, evaluate=False)
RootSum(Lambda(_a, -_a/(5*(x - _a))), x**5 + 1, x)

For more information on the implemented algorithm refer to:

[1] M. Bronstein, B. Salvy, Full partial fraction decomposition
of rational functions, in: M. Bronstein, ed., Proceedings ISSAC ‘93, ACM Press, Kiev, Ukraine, 1993, pp. 157-160.

Square Root Denest

sqrtdenest

sympy.simplify.sqrtdenest.sqrtdenest(expr)
Denests an expression that contains nested square roots. This algorithm is based on <http://www.almaden.ibm.com/cs/people/fagin/symb85.pdf>.

Common Subexpresion Elimination

cse

sympy.simplify.cse_main.cse(exprs, symbols=None, optimizations=None)

Perform common subexpression elimination on an expression.

Parameters:

exprs : list of sympy expressions, or a single sympy expression
The expressions to reduce.
symbols : infinite iterator yielding unique Symbols
The symbols used to label the common subexpressions which are pulled out. The numbered_symbols generator is useful. The default is a stream of symbols of the form “x0”, “x1”, etc. This must be an infinite iterator.
optimizations : list of (callable, callable) pairs, optional
The (preprocessor, postprocessor) pairs. If not provided, sympy.simplify.cse.cse_optimizations is used.

Returns:

replacements : list of (Symbol, expression) pairs
All of the common subexpressions that were replaced. Subexpressions earlier in this list might show up in subexpressions later in this list.
reduced_exprs : list of sympy expressions
The reduced expressions with all of the replacements above.