#NEWLINE# @ public #NEWLINE# def symmetrize( F , * gens , **args ) : #NEWLINE# #INDENT# '\n    Rewrite a polynomial in terms of elementary symmetric polynomials.\n\n    A symmetric polynomial is a multivariate polynomial that remains invariant\n    under any variable permutation, i.e., if ``f = f(x_1, x_2, ..., x_n)``,\n    then ``f = f(x_{i_1}, x_{i_2}, ..., x_{i_n})``, where\n    ``(i_1, i_2, ..., i_n)`` is a permutation of ``(1, 2, ..., n)`` (an\n    element of the group ``S_n``).\n\n    Returns a tuple of symmetric polynomials ``(f1, f2, ..., fn)`` such that\n    ``f = f1 + f2 + ... + fn``.\n\n    Examples\n    ========\n\n    >>> from sympy.polys.polyfuncs import symmetrize\n    >>> from sympy.abc import x, y\n\n    >>> symmetrize(x**2 + y**2)\n    (-2*x*y + (x + y)**2, 0)\n\n    >>> symmetrize(x**2 + y**2, formal=True)\n    (s1**2 - 2*s2, 0, [(s1, x + y), (s2, x*y)])\n\n    >>> symmetrize(x**2 - y**2)\n    (-2*x*y + (x + y)**2, -2*y**2)\n\n    >>> symmetrize(x**2 - y**2, formal=True)\n    (s1**2 - 2*s2, -2*y**2, [(s1, x + y), (s2, x*y)])\n\n    ' #NEWLINE# allowed_flags ( args , [ 'formal' , 'symbols' ] ) #NEWLINE# iterable = True #NEWLINE# if ( not hasattr ( F , '__iter__' ) ) : #NEWLINE# #INDENT# iterable = False #NEWLINE# F = [ F ] #NEWLINE# #UNINDENT# try : #NEWLINE# #INDENT# ( F , opt ) = parallel_poly_from_expr ( F , * gens , ** args ) #NEWLINE# #UNINDENT# except PolificationFailed as exc : #NEWLINE# #INDENT# result = [ ] #NEWLINE# for expr in exc . exprs : #NEWLINE# #INDENT# if expr . is_Number : #NEWLINE# #INDENT# result . append ( ( expr , S . Zero ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# raise ComputationFailed ( 'symmetrize' , len ( F ) , exc ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( not iterable ) : #NEWLINE# #INDENT# ( result , ) = result #NEWLINE# #UNINDENT# if ( not exc . opt . formal ) : #NEWLINE# #INDENT# return result #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if iterable : #NEWLINE# #INDENT# return ( result , [ ] ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# return ( result + ( [ ] , ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# ( polys , symbols ) = ( [ ] , opt . symbols ) #NEWLINE# ( gens , dom ) = ( opt . gens , opt . domain ) #NEWLINE# for i in range ( 0 , len ( gens ) ) : #NEWLINE# #INDENT# poly = symmetric_poly ( ( i + 1 ) , gens , polys = True ) #NEWLINE# polys . append ( ( next ( symbols ) , poly . set_domain ( dom ) ) ) #NEWLINE# #UNINDENT# indices = list ( range ( 0 , ( len ( gens ) - 1 ) ) ) #NEWLINE# weights = list ( range ( len ( gens ) , 0 , ( - 1 ) ) ) #NEWLINE# result = [ ] #NEWLINE# for f in F : #NEWLINE# #INDENT# symmetric = [ ] #NEWLINE# if ( not f . is_homogeneous ) : #NEWLINE# #INDENT# symmetric . append ( f . TC ( ) ) #NEWLINE# f -= f . TC ( ) #NEWLINE# #UNINDENT# while f : #NEWLINE# #INDENT# ( _height , _monom , _coeff ) = ( ( - 1 ) , None , None ) #NEWLINE# for ( i , ( monom , coeff ) ) in enumerate ( f . terms ( ) ) : #NEWLINE# #INDENT# if all ( ( ( monom [ i ] >= monom [ ( i + 1 ) ] ) for i in indices ) ) : #NEWLINE# #INDENT# height = max ( [ ( n * m ) for ( n , m ) in zip ( weights , monom ) ] ) #NEWLINE# if ( height > _height ) : #NEWLINE# #INDENT# ( _height , _monom , _coeff ) = ( height , monom , coeff ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# if ( _height != ( - 1 ) ) : #NEWLINE# #INDENT# ( monom , coeff ) = ( _monom , _coeff ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# exponents = [ ] #NEWLINE# for ( m1 , m2 ) in zip ( monom , ( monom [ 1 : ] + ( 0 , ) ) ) : #NEWLINE# #INDENT# exponents . append ( ( m1 - m2 ) ) #NEWLINE# #UNINDENT# term = [ ( s ** n ) for ( ( s , _ ) , n ) in zip ( polys , exponents ) ] #NEWLINE# poly = [ ( p ** n ) for ( ( _ , p ) , n ) in zip ( polys , exponents ) ] #NEWLINE# symmetric . append ( Mul ( coeff , * term ) ) #NEWLINE# product = poly [ 0 ] . mul ( coeff ) #NEWLINE# for p in poly [ 1 : ] : #NEWLINE# #INDENT# product = product . mul ( p ) #NEWLINE# #UNINDENT# f -= product #NEWLINE# #UNINDENT# result . append ( ( Add ( * symmetric ) , f . as_expr ( ) ) ) #NEWLINE# #UNINDENT# polys = [ ( s , p . as_expr ( ) ) for ( s , p ) in polys ] #NEWLINE# if ( not opt . formal ) : #NEWLINE# #INDENT# for ( i , ( sym , non_sym ) ) in enumerate ( result ) : #NEWLINE# #INDENT# result [ i ] = ( sym . subs ( polys ) , non_sym ) #NEWLINE# #UNINDENT# #UNINDENT# if ( not iterable ) : #NEWLINE# #INDENT# ( result , ) = result #NEWLINE# #UNINDENT# if ( not opt . formal ) : #NEWLINE# #INDENT# return result #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if iterable : #NEWLINE# #INDENT# return ( result , polys ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# return ( result + ( polys , ) )