Spaces:
Running
Running
"""Tools for manipulation of rational expressions. """ | |
from sympy.core import Basic, Add, sympify | |
from sympy.core.exprtools import gcd_terms | |
from sympy.utilities import public | |
from sympy.utilities.iterables import iterable | |
def together(expr, deep=False, fraction=True): | |
""" | |
Denest and combine rational expressions using symbolic methods. | |
This function takes an expression or a container of expressions | |
and puts it (them) together by denesting and combining rational | |
subexpressions. No heroic measures are taken to minimize degree | |
of the resulting numerator and denominator. To obtain completely | |
reduced expression use :func:`~.cancel`. However, :func:`~.together` | |
can preserve as much as possible of the structure of the input | |
expression in the output (no expansion is performed). | |
A wide variety of objects can be put together including lists, | |
tuples, sets, relational objects, integrals and others. It is | |
also possible to transform interior of function applications, | |
by setting ``deep`` flag to ``True``. | |
By definition, :func:`~.together` is a complement to :func:`~.apart`, | |
so ``apart(together(expr))`` should return expr unchanged. Note | |
however, that :func:`~.together` uses only symbolic methods, so | |
it might be necessary to use :func:`~.cancel` to perform algebraic | |
simplification and minimize degree of the numerator and denominator. | |
Examples | |
======== | |
>>> from sympy import together, exp | |
>>> from sympy.abc import x, y, z | |
>>> 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) | |
>>> together(1/(1 + 1/x) + 1/(1 + 1/y)) | |
(x*(y + 1) + y*(x + 1))/((x + 1)*(y + 1)) | |
>>> together(exp(1/x + 1/y)) | |
exp(1/y + 1/x) | |
>>> together(exp(1/x + 1/y), deep=True) | |
exp((x + y)/(x*y)) | |
>>> together(1/exp(x) + 1/(x*exp(x))) | |
(x + 1)*exp(-x)/x | |
>>> together(1/exp(2*x) + 1/(x*exp(3*x))) | |
(x*exp(x) + 1)*exp(-3*x)/x | |
""" | |
def _together(expr): | |
if isinstance(expr, Basic): | |
if expr.is_Atom or (expr.is_Function and not deep): | |
return expr | |
elif expr.is_Add: | |
return gcd_terms(list(map(_together, Add.make_args(expr))), fraction=fraction) | |
elif expr.is_Pow: | |
base = _together(expr.base) | |
if deep: | |
exp = _together(expr.exp) | |
else: | |
exp = expr.exp | |
return expr.func(base, exp) | |
else: | |
return expr.func(*[ _together(arg) for arg in expr.args ]) | |
elif iterable(expr): | |
return expr.__class__([ _together(ex) for ex in expr ]) | |
return expr | |
return _together(sympify(expr)) | |