(F, *gens, **args)
Rewrite a polynomial in terms of elementary symmetric polynomials.

    A symmetric polynomial is a multivariate polynomial that remains invariant
    under any variable permutation, i.e., if ``f = f(x_1, x_2, ..., x_n)``,
    then ``f = f(x_{i_1}, x_{i_2}, ..., x_{i_n})``, where
    ``(i_1, i_2, ..., i_n)`` is a permutation of ``(1, 2, ..., n)`` (an
    element of the group ``S_n``).

    Returns a tuple of symmetric polynomials ``(f1, f2, ..., fn)`` such that
    ``f = f1 + f2 + ... + fn``.

    Examples
    ========

    >>> from sympy.polys.polyfuncs import symmetrize
    >>> from sympy.abc import x, y

    >>> symmetrize(x**2 + y**2)
    (-2*x*y + (x + y)**2, 0)

    >>> symmetrize(x**2 + y**2, formal=True)
    (s1**2 - 2*s2, 0, [(s1, x + y), (s2, x*y)])

    >>> symmetrize(x**2 - y**2)
    (-2*x*y + (x + y)**2, -2*y**2)

    >>> symmetrize(x**2 - y**2, formal=True)
    (s1**2 - 2*s2, -2*y**2, [(s1, x + y), (s2, x*y)])
Rewrite a polynomial in terms of elementary symmetric polynomials.
Rewrite a polynomial in terms of elementary symmetric polynomials .
def symmetrize(F, *gens, **args):
    """
    Rewrite a polynomial in terms of elementary symmetric polynomials.

    A symmetric polynomial is a multivariate polynomial that remains invariant
    under any variable permutation, i.e., if ``f = f(x_1, x_2, ..., x_n)``,
    then ``f = f(x_{i_1}, x_{i_2}, ..., x_{i_n})``, where
    ``(i_1, i_2, ..., i_n)`` is a permutation of ``(1, 2, ..., n)`` (an
    element of the group ``S_n``).

    Returns a tuple of symmetric polynomials ``(f1, f2, ..., fn)`` such that
    ``f = f1 + f2 + ... + fn``.

    Examples
    ========

    >>> from sympy.polys.polyfuncs import symmetrize
    >>> from sympy.abc import x, y

    >>> symmetrize(x**2 + y**2)
    (-2*x*y + (x + y)**2, 0)

    >>> symmetrize(x**2 + y**2, formal=True)
    (s1**2 - 2*s2, 0, [(s1, x + y), (s2, x*y)])

    >>> symmetrize(x**2 - y**2)
    (-2*x*y + (x + y)**2, -2*y**2)

    >>> symmetrize(x**2 - y**2, formal=True)
    (s1**2 - 2*s2, -2*y**2, [(s1, x + y), (s2, x*y)])

    """
    allowed_flags(args, ['formal', 'symbols'])

    iterable = True

    if not hasattr(F, '__iter__'):
        iterable = False
        F = [F]

    try:
        F, opt = parallel_poly_from_expr(F, *gens, **args)
    except PolificationFailed as exc:
        result = []

        for expr in exc.exprs:
            if expr.is_Number:
                result.append((expr, S.Zero))
            else:
                raise ComputationFailed('symmetrize', len(F), exc)
        else:
            if not iterable:
                result, = result

            if not exc.opt.formal:
                return result
            else:
                if iterable:
                    return result, []
                else:
                    return result + ([],)

    polys, symbols = [], opt.symbols
    gens, dom = opt.gens, opt.domain

    for i in xrange(0, len(gens)):
        poly = symmetric_poly(i + 1, gens, polys=True)
        polys.append((next(symbols), poly.set_domain(dom)))

    indices = list(range(0, len(gens) - 1))
    weights = list(range(len(gens), 0, -1))

    result = []

    for f in F:
        symmetric = []

        if not f.is_homogeneous:
            symmetric.append(f.TC())
            f -= f.TC()

        while f:
            _height, _monom, _coeff = -1, None, None

            for i, (monom, coeff) in enumerate(f.terms()):
                if all(monom[i] >= monom[i + 1] for i in indices):
                    height = max([ n*m for n, m in zip(weights, monom) ])

                    if height > _height:
                        _height, _monom, _coeff = height, monom, coeff

            if _height != -1:
                monom, coeff = _monom, _coeff
            else:
                break

            exponents = []

            for m1, m2 in zip(monom, monom[1:] + (0,)):
                exponents.append(m1 - m2)

            term = [ s**n for (s, _), n in zip(polys, exponents) ]
            poly = [ p**n for (_, p), n in zip(polys, exponents) ]

            symmetric.append(Mul(coeff, *term))
            product = poly[0].mul(coeff)

            for p in poly[1:]:
                product = product.mul(p)

            f -= product

        result.append((Add(*symmetric), f.as_expr()))

    polys = [ (s, p.as_expr()) for s, p in polys ]

    if not opt.formal:
        for i, (sym, non_sym) in enumerate(result):
            result[i] = (sym.subs(polys), non_sym)

    if not iterable:
        result, = result

    if not opt.formal:
        return result
    else:
        if iterable:
            return result, polys
        else:
            return result + (polys,)
def symmetrize ( F , * gens , * * args ) : allowed_flags ( args , [ 'formal' , 'symbols' ] ) iterable = True if not hasattr ( F , '__iter__' ) : iterable = False F = [ F ] try : F , opt = parallel_poly_from_expr ( F , * gens , * * args ) except PolificationFailed as exc : result = [ ] for expr in exc . exprs : if expr . is_Number : result . append ( ( expr , S . Zero ) ) else : raise ComputationFailed ( 'symmetrize' , len ( F ) , exc ) else : if not iterable : result , = result if not exc . opt . formal : return result else : if iterable : return result , [ ] else : return result + ( [ ] , ) polys , symbols = [ ] , opt . symbols gens , dom = opt . gens , opt . domain for i in xrange ( 0 , len ( gens ) ) : poly = symmetric_poly ( i + 1 , gens , polys = True ) polys . append ( ( next ( symbols ) , poly . set_domain ( dom ) ) ) indices = list ( range ( 0 , len ( gens ) - 1 ) ) weights = list ( range ( len ( gens ) , 0 , - 1 ) ) result = [ ] for f in F : symmetric = [ ] if not f . is_homogeneous : symmetric . append ( f . TC ( ) ) f -= f . TC ( ) while f : _height , _monom , _coeff = - 1 , None , None for i , ( monom , coeff ) in enumerate ( f . terms ( ) ) : if all ( monom [ i ] >= monom [ i + 1 ] for i in indices ) : height = max ( [ n * m for n , m in zip ( weights , monom ) ] ) if height > _height : _height , _monom , _coeff = height , monom , coeff if _height != - 1 : monom , coeff = _monom , _coeff else : break exponents = [ ] for m1 , m2 in zip ( monom , monom [ 1 : ] + ( 0 , ) ) : exponents . append ( m1 - m2 ) term = [ s ** n for ( s , _ ) , n in zip ( polys , exponents ) ] poly = [ p ** n for ( _ , p ) , n in zip ( polys , exponents ) ] symmetric . append ( Mul ( coeff , * term ) ) product = poly [ 0 ] . mul ( coeff ) for p in poly [ 1 : ] : product = product . mul ( p ) f -= product result . append ( ( Add ( * symmetric ) , f . as_expr ( ) ) ) polys = [ ( s , p . as_expr ( ) ) for s , p in polys ] if not opt . formal : for i , ( sym , non_sym ) in enumerate ( result ) : result [ i ] = ( sym . subs ( polys ) , non_sym ) if not iterable : result , = result if not opt . formal : return result else : if iterable : return result , polys else : return result + ( polys , )