(f, x=None, full=False, **options)
return common*(poly.as_expr() + terms)
Compute partial fraction decomposition of a rational function.

    Given a rational function ``f`` compute partial fraction decomposition
    of ``f``. Two algorithms are available: one is based on undetermined
    coefficients method and the other is Bronstein's full partial fraction
    decomposition algorithm.

    Examples
    ========

    >>> from sympy.polys.partfrac import apart
    >>> from sympy.abc import x, y

    By default, using the undetermined coefficients method:

    >>> apart(y/(x + 2)/(x + 1), x)
    -y/(x + 2) + y/(x + 1)

    You can choose Bronstein's algorithm by setting ``full=True``:

    >>> apart(y/(x**2 + x + 1), x)
    y/(x**2 + x + 1)
    >>> apart(y/(x**2 + x + 1), x, full=True)
    RootSum(_w**2 + _w + 1, Lambda(_a, (-2*_a*y/3 - y/3)/(-_a + x)))

    See Also
    ========

    apart_list, assemble_partfrac_list
Compute partial fraction decomposition of a rational function.
Compute partial fraction decomposition of a rational function .
def apart(f, x=None, full=False, **options):
    """
    Compute partial fraction decomposition of a rational function.

    Given a rational function ``f`` compute partial fraction decomposition
    of ``f``. Two algorithms are available: one is based on undetermined
    coefficients method and the other is Bronstein's full partial fraction
    decomposition algorithm.

    Examples
    ========

    >>> from sympy.polys.partfrac import apart
    >>> from sympy.abc import x, y

    By default, using the undetermined coefficients method:

    >>> apart(y/(x + 2)/(x + 1), x)
    -y/(x + 2) + y/(x + 1)

    You can choose Bronstein's algorithm by setting ``full=True``:

    >>> apart(y/(x**2 + x + 1), x)
    y/(x**2 + x + 1)
    >>> apart(y/(x**2 + x + 1), x, full=True)
    RootSum(_w**2 + _w + 1, Lambda(_a, (-2*_a*y/3 - y/3)/(-_a + x)))

    See Also
    ========

    apart_list, assemble_partfrac_list
    """
    allowed_flags(options, [])

    f = sympify(f)

    if f.is_Atom:
        return f
    else:
        P, Q = f.as_numer_denom()

    _options = options.copy()
    options = set_defaults(options, extension=True)
    try:
        (P, Q), opt = parallel_poly_from_expr((P, Q), x, **options)
    except PolynomialError as msg:
        if f.is_commutative:
            raise PolynomialError(msg)
        # non-commutative
        if f.is_Mul:
            c, nc = f.args_cnc(split_1=False)
            nc = f.func(*[apart(i, x=x, full=full, **_options) for i in nc])
            if c:
                c = apart(f.func._from_args(c), x=x, full=full, **_options)
                return c*nc
            else:
                return nc
        elif f.is_Add:
            c = []
            nc = []
            for i in f.args:
                if i.is_commutative:
                    c.append(i)
                else:
                    try:
                        nc.append(apart(i, x=x, full=full, **_options))
                    except NotImplementedError:
                        nc.append(i)
            return apart(f.func(*c), x=x, full=full, **_options) + f.func(*nc)
        else:
            reps = []
            pot = preorder_traversal(f)
            next(pot)
            for e in pot:
                try:
                    reps.append((e, apart(e, x=x, full=full, **_options)))
                    pot.skip()  # this was handled successfully
                except NotImplementedError:
                    pass
            return f.xreplace(dict(reps))

    if P.is_multivariate:
        fc = f.cancel()
        if fc != f:
            return apart(fc, x=x, full=full, **_options)

        raise NotImplementedError(
            "multivariate partial fraction decomposition")

    common, P, Q = P.cancel(Q)

    poly, P = P.div(Q, auto=True)
    P, Q = P.rat_clear_denoms(Q)

    if Q.degree() <= 1:
        partial = P/Q
    else:
        if not full:
            partial = apart_undetermined_coeffs(P, Q)
        else:
            partial = apart_full_decomposition(P, Q)

    terms = S.Zero

    for term in Add.make_args(partial):
        if term.has(RootSum):
            terms += term
        else:
            terms += factor(term)

    return common*(poly.as_expr() + terms)
def apart ( f , x = None , full = False , * * options ) : allowed_flags ( options , [ ] ) f = sympify ( f ) if f . is_Atom : return f else : P , Q = f . as_numer_denom ( ) _options = options . copy ( ) options = set_defaults ( options , extension = True ) try : ( P , Q ) , opt = parallel_poly_from_expr ( ( P , Q ) , x , * * options ) except PolynomialError as msg : if f . is_commutative : raise PolynomialError ( msg ) # non-commutative if f . is_Mul : c , nc = f . args_cnc ( split_1 = False ) nc = f . func ( * [ apart ( i , x = x , full = full , * * _options ) for i in nc ] ) if c : c = apart ( f . func . _from_args ( c ) , x = x , full = full , * * _options ) return c * nc else : return nc elif f . is_Add : c = [ ] nc = [ ] for i in f . args : if i . is_commutative : c . append ( i ) else : try : nc . append ( apart ( i , x = x , full = full , * * _options ) ) except NotImplementedError : nc . append ( i ) return apart ( f . func ( * c ) , x = x , full = full , * * _options ) + f . func ( * nc ) else : reps = [ ] pot = preorder_traversal ( f ) next ( pot ) for e in pot : try : reps . append ( ( e , apart ( e , x = x , full = full , * * _options ) ) ) pot . skip ( ) # this was handled successfully except NotImplementedError : pass return f . xreplace ( dict ( reps ) ) if P . is_multivariate : fc = f . cancel ( ) if fc != f : return apart ( fc , x = x , full = full , * * _options ) raise NotImplementedError ( "multivariate partial fraction decomposition" ) common , P , Q = P . cancel ( Q ) poly , P = P . div ( Q , auto = True ) P , Q = P . rat_clear_denoms ( Q ) if Q . degree ( ) <= 1 : partial = P / Q else : if not full : partial = apart_undetermined_coeffs ( P , Q ) else : partial = apart_full_decomposition ( P , Q ) terms = S . Zero for term in Add . make_args ( partial ) : if term . has ( RootSum ) : terms += term else : terms += factor ( term ) return common * ( poly . as_expr ( ) + terms )