B
    ['                 @   s   d Z ddlmZmZ ddlmZmZmZ ddlm	Z	 ddl
mZmZ ddlmZmZmZmZ ddlmZmZmZ ddlmZmZmZmZmZ dd	lmZ dd
lmZ edd Z edd Z!edd Z"eedfddZ#edddZ$dS )z/High-level polynomials manipulation functions.     )print_functiondivision)poly_from_exprparallel_poly_from_exprPoly)allowed_flags)symmetric_polyinterpolating_poly)PolificationFailedComputationFailedMultivariatePolynomialErrorOptionError)numbered_symbolstakepublic)SBasicAddMulsymbols)range)	factorialc          
      s`  t |ddg d}t| ds&d}| g} yt| f||\} }W n tk
r } zlg }xb|jD ],}|jrx||tjf q\t	dt
| |q\W |s|\}|jjs|S |r|g fS |g f S W dd}~X Y nX g |j }}	|j|j }}
x>tt
|D ].}t|d |dd	}|t|	||
f qW ttt
|d }ttt
|d
d}g }x| D ]}g }|js||  || 8 }xD|rd\}}}xht| D ]X\}\ }t fdd|D rtdd t| D }||kr| |  }}}qW |dkr||  }nP g }x2t  dd d D ]\}}|||  q6W dd t||D }dd t||D }|t|f|  |d
 |}x |dd D ]}||}qW ||8 }qW |t| | f qXW dd |D }|js,x,t|D ] \}\}}| ||f||< qW |s8|\}|jsD|S |rR||fS ||f S dS )a  
    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)])

    formalr   T__iter__F
symmetrizeN   )polysr   )r   NNc             3   s"   | ]} |  |d   kV  qdS )r   N ).0i)monomr   4lib/python3.7/site-packages/sympy/polys/polyfuncs.py	<genexpr>n   s    zsymmetrize.<locals>.<genexpr>c             S   s   g | ]\}}|| qS r   r   )r   nmr   r   r"   
<listcomp>o   s    zsymmetrize.<locals>.<listcomp>)r   c             S   s   g | ]\\}}}|| qS r   r   )r   s_r$   r   r   r"   r&   ~   s    c             S   s   g | ]\\}}}|| qS r   r   )r   r(   pr$   r   r   r"   r&      s    c             S   s   g | ]\}}||  fqS r   )as_expr)r   r'   r)   r   r   r"   r&      s    )!r   hasattrr   r
   ZexprsZ	is_Numberappendr   Zeror   lenoptr   r   gensZdomainr   r   nextZ
set_domainlistZis_homogeneousZTC	enumerateZtermsallmaxzipr   mulr   r*   Zsubs)Fr0   argsiterabler/   excresultexprr   r   Zdomr    polyindicesZweightsfZ	symmetricZ_heightZ_monomZ_coeffcoeffZheightZ	exponentsZm1Zm2Ztermproductr)   ZsymZnon_symr   )r!   r"   r      s    !




 r   c       	   
   O   s   t |g  yt| f||\}}W n$ tk
rF } z|jS d}~X Y nX tj|j }}|jr|x`| D ]}|| | }qfW nBt	|||dd  }}x(| D ]}|| t
|f|| }qW |S )a  
    Rewrite a polynomial in Horner form.

    Among other applications, evaluation of a polynomial at a point is optimal
    when it is applied using the Horner scheme ([1]).

    Examples
    ========

    >>> from sympy.polys.polyfuncs import horner
    >>> from sympy.abc import x, y, a, b, c, d, e

    >>> horner(9*x**4 + 8*x**3 + 7*x**2 + 6*x + 5)
    x*(x*(x*(9*x + 8) + 7) + 6) + 5

    >>> horner(a*x**4 + b*x**3 + c*x**2 + d*x + e)
    e + x*(d + x*(c + x*(a*x + b)))

    >>> f = 4*x**2*y**2 + 2*x**2*y + 2*x*y**2 + x*y

    >>> horner(f, wrt=x)
    x*(x*y*(4*y + 2) + y*(2*y + 1))

    >>> horner(f, wrt=y)
    y*(x*y*(4*x + 2) + x*(2*x + 1))

    References
    ==========
    [1] - http://en.wikipedia.org/wiki/Horner_scheme

    Nr   )r   r   r
   r=   r   r-   genZis_univariate
all_coeffsr   horner)	r@   r0   r9   r8   r/   r;   ZformrC   rA   r   r   r"   rE      s    !
rE   c       
         s  t | }d}t| tr:tt|   \}}t| ||}nt| d trhtt|  \}}t| ||}nt| }t fddt	d|d D  }|d dkrt
|d  n
t
|d }g }x<t	d|d D ]*}	|| |	  |  ||	|  |	 }qW tdd t||D  }| S )a  
    Construct an interpolating polynomial for the data points.

    Examples
    ========

    >>> from sympy.polys.polyfuncs import interpolate
    >>> from sympy.abc import x

    A list is interpreted as though it were paired with a range starting
    from 1:

    >>> interpolate([1, 4, 9, 16], x)
    x**2

    This can be made explicit by giving a list of coordinates:

    >>> interpolate([(1, 1), (2, 4), (3, 9)], x)
    x**2

    The (x, y) coordinates can also be given as keys and values of a
    dictionary (and the points need not be equispaced):

    >>> interpolate([(-1, 2), (1, 2), (2, 5)], x)
    x**2 + 1
    >>> interpolate({-1: 2, 1: 2, 2: 5}, x)
    x**2 + 1

    Nr   c                s   g | ]} | qS r   r   )r   r    )xr   r"   r&      s    zinterpolate.<locals>.<listcomp>r      c             S   s   g | ]\}}|| qS r   r   )r   rA   yr   r   r"   r&     s    )r.   
isinstancedictr2   r6   itemsr	   tupler   r   r   r,   r   expand)
datarF   r$   r>   XYZnumertZdenomcoeffsr    r   )rF   r"   interpolate   s"    
 &rR   rF   c       
         sT  ddl m} tt|  \}}t| d }|dk r<td|| d | d }xPtt|D ]>}x8t| d D ]$}	||	|f ||	  ||	|d f< q|W qfW x\t|d D ]L}xFt| d D ]2}	||	|| f  ||	  ||	| d | f< qW qW | d t	 fddtd D t	 fddt|d D  S )	a  
    Returns a rational interpolation, where the data points are element of
    any integral domain.

    The first argument  contains the data (as a list of coordinates). The
    ``degnum`` argument is the degree in the numerator of the rational
    function. Setting it too high will decrease the maximal degree in the
    denominator for the same amount of data.

    Examples
    ========
    >>> from sympy.polys.polyfuncs import rational_interpolate

    >>> data = [(1, -210), (2, -35), (3, 105), (4, 231), (5, 350), (6, 465)]
    >>> rational_interpolate(data, 2)
    (105*x**2 - 525)/(x + 1)

    Values do not need to be integers:

    >>> from sympy import sympify
    >>> x = [1, 2, 3, 4, 5, 6]
    >>> y = sympify("[-1, 0, 2, 22/5, 7, 68/7]")
    >>> rational_interpolate(zip(x, y), 2)
    (3*x**2 - 7*x + 2)/(x + 1)

    The symbol for the variable can be changed if needed:
    >>> from sympy import symbols
    >>> z = symbols('z')
    >>> rational_interpolate(data, 2, X=z)
    (105*z**2 - 525)/(z + 1)

    References
    ==========
    Algorithm is adapted from:
        http://axiom-wiki.newsynthesis.org/RationalInterpolation

    r   )onesr   z'Too few values for the required degree.rG   c             3   s   | ]}|  |  V  qd S )Nr   )r   r    )rO   rr   r"   r#   A  s    z'rational_interpolate.<locals>.<genexpr>c             3   s&   | ]}| d    |  V  qdS )r   Nr   )r   r    )rO   degnumrT   r   r"   r#   B  s    )
Zsympy.matrices.denserS   r2   r6   r.   r   r   r5   Z	nullspacesum)
rN   rU   rO   rS   ZxdataZydatakcjr    r   )rO   rU   rT   r"   rational_interpolate  s    '(6rZ   Nc          
   O   s>  t |g  t|tr$|f| d }}yt| f||\} }W n. tk
rj } ztdd|W dd}~X Y nX | jrztd|  }|dk rt	d|dkrt
ddd}t||}|t|krt	d|t|f |  |   }}g d	 }	}
xLt|dd D ]8\}}t|d |}|
||  }|	||f |
 }
 qW |	S )
a#  
    Generate Viete's formulas for ``f``.

    Examples
    ========

    >>> from sympy.polys.polyfuncs import viete
    >>> from sympy import symbols

    >>> x, a, b, c, r1, r2 = symbols('x,a:c,r1:3')

    >>> viete(a*x**2 + b*x + c, [r1, r2], x)
    [(r1 + r2, -b/a), (r1*r2, c/a)]

    Nvieter   z(multivariate polynomials are not allowedz7can't derive Viete's formulas for a constant polynomialrT   )startzrequired %s roots, got %sr   )r   rI   r   r   r
   r   Zis_multivariater   Zdegree
ValueErrorr   r   r.   ZLCrD   r3   r   r,   )r@   rootsr0   r9   r/   r;   r$   ZlcrQ   r<   Zsignr    rA   r>   r   r   r"   r[   E  s6    



r[   )N)%__doc__Z
__future__r   r   Zsympy.polys.polytoolsr   r   r   Zsympy.polys.polyoptionsr   Zsympy.polys.specialpolysr   r	   Zsympy.polys.polyerrorsr
   r   r   r   Zsympy.utilitiesr   r   r   Z
sympy.corer   r   r   r   r   Zsympy.core.compatibilityr   Z(sympy.functions.combinatorial.factorialsr   r   rE   rR   rZ   r[   r   r   r   r"   <module>   s"    689