U
    ZÊ¹jDl  ã                   @   s@  d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	m
Z
 ddlmZ ddlmZmZmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlm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& ddl'm(Z(m)Z)m*Z* ddl+m,Z, ddl-m.Z.m/Z/ ddl0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z: ddl;m<Z<m=Z= ddl>m?Z? ddl@mAZA ddlBmCZC ddlDmEZE ddlFmGZGmHZHmIZI e)ddfdd„ZJdd „ ZKd!d"„ ZLd#d$„ ZMdFd&d'„ZNd(d)„ ZOd*d+„ ZPdGd,d-„ZQd.d/„ ZRd0d1„ ZSd2d3„ ZTd4d5„ ZUd6d7„ ZVd8d9„ ZWd:d;„ ZXd<d=„ ZYeHdHd@dA„ƒZZdBdC„ Z[eHdIdDdE„ƒZ\d%S )Jz*Minimal polynomials for algebraic numbers.é    )Úreduce)ÚAdd)ÚFactors)Ú
expand_mulÚexpand_multinomialÚ_mexpand)ÚMul)ÚIÚRationalÚpiÚ_illegal)ÚS)ÚDummy)Úsympify)Úpreorder_traversal)Úexp)ÚsqrtÚcbrt)ÚcosÚsinÚtan)Údivisors)Úsubsets)ÚZZÚQQÚFractionField)Údup_chebyshevt)ÚNotAlgebraicÚGeneratorsError)
ÚPolyÚPurePolyÚinvertÚfactor_listÚgroebnerÚ	resultantÚdegreeÚpoly_from_exprÚparallel_poly_from_exprÚlcm)Údict_from_exprÚexpr_from_dict)Úrs_compose_add)Úring)ÚCRootOf©Úcyclotomic_poly)Únumbered_symbolsÚpublicÚsiftéÈ   é   c                    s8  t | d tƒrdd„ | D ƒ} t| ƒdkr0| d S d‰i ‰ t|dƒrH|jng }ˆˆk�r(‡‡fdd„| D ƒ}ˆjr‚‡fdd„|D ƒ}tt|ƒt|ƒd	d
�D ]„}t||ƒD ]\}	}
|
ˆ |	< q¦‡ ‡fdd„t	|ƒD ƒ}t
dd„ |D ƒƒräq˜t|ƒ}|dd… \\}}\}}||d kr˜| |   S q˜ˆd9 ‰qLtdˆ ƒ‚dS )ze
    Return a factor having root ``v``
    It is assumed that one of the factors has root ``v``.
    r   c                 S   s   g | ]}|d  ‘qS )r   © ©Ú.0Úfr5   r5   ú_/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/polys/numberfields/minpoly.pyÚ
<listcomp>/   s     z"_choose_factor.<locals>.<listcomp>é   é
   Úsymbolsc                    s   g | ]}|  ¡  ˆˆ i¡‘qS r5   )Úas_exprZxreplacer6   )ÚvÚxr5   r9   r:   9   s     c                    s   g | ]}|  ˆ ¡‘qS r5   )Únr6   )Úprecr5   r9   r:   ;   s     T)ÚkZ
repetitionc                    s(   g | ] \}}t | ˆ ¡ ˆ¡ƒ|f‘qS r5   )ÚabsÚsubsrA   )r7   Úir8   )ÚpointsÚprec1r5   r9   r:   C   s   ÿc                 s   s   | ]\}}|t kV  qd S ©N)r   )r7   rF   Ú_r5   r5   r9   Ú	<genexpr>H   s     z!_choose_factor.<locals>.<genexpr>Né   i@B z4multiple candidates for the minimal polynomial of %s)Ú
isinstanceÚtupleÚlenÚhasattrr=   Ú	is_numberr   ÚrangeÚzipÚ	enumerateÚanyÚsortedÚNotImplementedError)Úfactorsr@   r?   ÚdomrB   Úboundr=   ZferA   ÚsrF   Ú
candidatesZcanÚaZixÚbrJ   r5   )rG   rB   rH   r?   r@   r9   Ú_choose_factor(   s2    

ÿ
r_   c                 C   s6   | j r| jn| g}|D ]}|d jr*|js dS qdS )NrL   FT)Úis_AddÚargsÚis_RationalZis_extended_real)Úpra   Úyr5   r5   r9   Ú_is_sum_surdsX   s
    re   c                 C   s˜  dd„ }g }| j D ]”}|jsx||ƒr:| tj|d f¡ q¦|jrR| |tjf¡ q¦|jrr|jjrr| |tjf¡ q¦t	‚qt
|j |dd�\}}| t|Ž t|Ž d f¡ q|jdd„ d� |d	 d
 tjkrÎ| S dd„ |D ƒ}tt|ƒƒD ]}|| d
krè qþqèddlm} |||d… Ž \}	}
}g }g }|D ]>\}}||
k�rT| ||tj  ¡ n| ||tj  ¡ �q,t|Ž }t|Ž }t|d ƒt|d ƒ } | S )a?  
    helper function for ``_minimal_polynomial_sq``

    It selects a rational ``g`` such that the polynomial ``p``
    consists of a sum of terms whose surds squared have gcd equal to ``g``
    and a sum of terms with surds squared prime with ``g``;
    then it takes the field norm to eliminate ``sqrt(g)``

    See simplify.simplify.split_surds and polytools.sqf_norm.

    Examples
    ========

    >>> from sympy import sqrt
    >>> from sympy.abc import x
    >>> from sympy.polys.numberfields.minpoly import _separate_sq
    >>> p= -x + sqrt(2) + sqrt(3) + sqrt(7)
    >>> p = _separate_sq(p); p
    -x**2 + 2*sqrt(3)*x + 2*sqrt(7)*x - 2*sqrt(21) - 8
    >>> p = _separate_sq(p); p
    -x**4 + 4*sqrt(7)*x**3 - 32*x**2 + 8*sqrt(7)*x + 20
    >>> p = _separate_sq(p); p
    -x**8 + 48*x**6 - 536*x**4 + 1728*x**2 - 400

    c                 S   s   | j o| jtjkS rI   )Úis_Powr   r   ÚHalf)Úexprr5   r5   r9   Úis_sqrtz   s    z_separate_sq.<locals>.is_sqrtrL   T)Úbinaryc                 S   s   | d S )Nr;   r5   )Úzr5   r5   r9   Ú<lambda>‹   ó    z_separate_sq.<locals>.<lambda>)Úkeyéÿÿÿÿr;   c                 S   s   g | ]\}}|‘qS r5   r5   )r7   rd   rk   r5   r5   r9   r:   �   s     z _separate_sq.<locals>.<listcomp>r   )Ú
_split_gcdN)ra   Úis_MulÚappendr   ÚOneÚis_Atomrf   r   Ú
is_integerrW   r2   r   ÚsortrR   rO   Zsympy.simplify.radsimprp   rg   r   r   )rc   ri   r]   rd   ÚTÚFZsurdsrF   rp   ÚgÚb1Úb2Za1Za2rk   Úp1Úp2r5   r5   r9   Ú_separate_sq`   s@    

r~   c                 C   sÆ   t | ƒ} t |ƒ}|jr&|dkr&t| ƒs*dS | td|ƒ }| |8 } t| ƒ}|| krf| ||| i¡} qlq@|} q@|dkrªt| ƒ}|  || |¡ ¡dk rš|  } |  	¡ d } | S t
| ƒd }t|||ƒ}|S )a  
    Returns the minimal polynomial for the ``nth-root`` of a sum of surds
    or ``None`` if it fails.

    Parameters
    ==========

    p : sum of surds
    n : positive integer
    x : variable of the returned polynomial

    Examples
    ========

    >>> from sympy.polys.numberfields.minpoly import _minimal_polynomial_sq
    >>> from sympy import sqrt
    >>> from sympy.abc import x
    >>> q = 1 + sqrt(2) + sqrt(3)
    >>> _minimal_polynomial_sq(q, 3, x)
    x**12 - 4*x**9 - 4*x**6 + 16*x**3 - 8

    r   Nr;   )r   Ú
is_Integerre   r
   r~   rE   r   Úcoeffr%   Ú	primitiver"   r_   )rc   rA   r@   Zpnr|   rX   Úresultr5   r5   r9   Ú_minimal_polynomial_sq¡   s(    rƒ   Nc                 C   sz  t t|ƒƒ}|dkr t|||ƒ}|dkr6t|||ƒ}n| ||i¡}| tkr´|tkr„tdtƒ\}}	|t|ƒd ƒ}
|t|ƒd ƒ}qÒt||| f||ƒ\\}
}}|
 	|¡}| 
¡ }n| tkrÊt|||ƒ}ntdƒ‚| tksâ|tkröt||||gd�}nt|
|ƒ}t| ¡ |ƒ}t||ƒ}t||ƒ}| tk�r6|dk�s@|dk�rD|S t|||d�}| ¡ \}}t||| ||ƒ|ƒ}| 
¡ S )aÜ  
    return the minimal polynomial for ``op(ex1, ex2)``

    Parameters
    ==========

    op : operation ``Add`` or ``Mul``
    ex1, ex2 : expressions for the algebraic elements
    x : indeterminate of the polynomials
    dom: ground domain
    mp1, mp2 : minimal polynomials for ``ex1`` and ``ex2`` or None

    Examples
    ========

    >>> from sympy import sqrt, Add, Mul, QQ
    >>> from sympy.polys.numberfields.minpoly import _minpoly_op_algebraic_element
    >>> from sympy.abc import x, y
    >>> p1 = sqrt(sqrt(2) + 1)
    >>> p2 = sqrt(sqrt(2) - 1)
    >>> _minpoly_op_algebraic_element(Mul, p1, p2, x, QQ)
    x - 1
    >>> q1 = sqrt(y)
    >>> q2 = 1 / y
    >>> _minpoly_op_algebraic_element(Add, q1, q2, x, QQ.frac_field(y))
    x**2*y**2 - 2*x*y - y**3 + 1

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Resultant
    .. [2] I.M. Isaacs, Proc. Amer. Math. Soc. 25 (1970), 638
           "Degrees of sums in a separable field extension".

    NÚXr   zoption not available©Úgensr;   ©Údomain)r   ÚstrÚ_minpoly_composerE   r   r   r,   r)   r'   Úcomposer>   r   Ú_mulyrW   r$   r+   r*   Zas_expr_dictr%   r   r"   r_   )ÚopÚex1Úex2r@   rY   Úmp1Úmp2rd   ÚRr„   r|   r}   rJ   ÚrZmp1aZdeg1Zdeg2rX   Úresr5   r5   r9   Ú_minpoly_op_algebraic_element×   s:    $




r•   c                    s6   t | ˆƒd }t|ƒ‰ ‡ ‡fdd„| ¡ D ƒ}t|Ž S )z@
    Returns ``expand_mul(x**degree(p, x)*p.subs(x, 1/x))``
    r   c                    s"   g | ]\\}}|ˆˆ |   ‘qS r5   r5   ©r7   rF   Úc©rA   r@   r5   r9   r:   -  s     z_invertx.<locals>.<listcomp>©r&   r%   Útermsr   )rc   r@   r|   r]   r5   r˜   r9   Ú_invertx&  s    r›   c                    s8   t | ˆƒd }t|ƒ‰ ‡ ‡‡fdd„| ¡ D ƒ}t|Ž S )z8
    Returns ``_mexpand(y**deg*p.subs({x:x / y}))``
    r   c                    s*   g | ]"\\}}|ˆ|  ˆˆ |   ‘qS r5   r5   r–   ©rA   r@   rd   r5   r9   r:   8  s     z_muly.<locals>.<listcomp>r™   )rc   r@   rd   r|   r]   r5   rœ   r9   rŒ   1  s    rŒ   c                 C   sÜ   t |ƒ}|st| ||ƒ}|js*td|  ƒ‚|dk rj||krFtd|  ƒ‚t||ƒ}|dkr\|S | }d|  } tt|ƒƒ}| ||i¡}| 	¡ \}}t
t||| ||  |gd�||d�}| ¡ \}	}
t|
|| | |ƒ}| ¡ S )a”  
    Returns ``minpoly(ex**pw, x)``

    Parameters
    ==========

    ex : algebraic element
    pw : rational number
    x : indeterminate of the polynomial
    dom: ground domain
    mp : minimal polynomial of ``p``

    Examples
    ========

    >>> from sympy import sqrt, QQ, Rational
    >>> from sympy.polys.numberfields.minpoly import _minpoly_pow, minpoly
    >>> from sympy.abc import x, y
    >>> p = sqrt(1 + sqrt(2))
    >>> _minpoly_pow(p, 2, x, QQ)
    x**2 - 2*x - 1
    >>> minpoly(p**2, x)
    x**2 - 2*x - 1
    >>> _minpoly_pow(y, Rational(1, 3), x, QQ.frac_field(y))
    x**3 - y
    >>> minpoly(y**Rational(1, 3), x)
    x**3 - y

    ú+%s does not seem to be an algebraic elementr   z
%s is zeroro   r;   r…   r‡   )r   rŠ   Úis_rationalr   ÚZeroDivisionErrorr›   r   r‰   rE   Zas_numer_denomr   r$   r"   r_   r>   )ÚexÚpwr@   rY   Úmprd   rA   Údr”   rJ   rX   r5   r5   r9   Ú_minpoly_pow<  s(    
&r¤   c              	   G   sZ   t t|d |d | |ƒ}|d |d  }|dd… D ] }t t||| ||d�}|| }q4|S )z.
    returns ``minpoly(Add(*a), dom, x)``
    r   r;   rL   N©r�   )r•   r   ©r@   rY   r]   r¢   rc   Zpxr5   r5   r9   Ú_minpoly_addq  s    
r§   c              	   G   sZ   t t|d |d | |ƒ}|d |d  }|dd… D ] }t t||| ||d�}|| }q4|S )z.
    returns ``minpoly(Mul(*a), dom, x)``
    r   r;   rL   Nr¥   )r•   r   r¦   r5   r5   r9   Ú_minpoly_mul}  s    
r¨   c           	         s0  | j d  ¡ \}‰ ˆ tk�r |j�r |j‰tˆƒ}|jr`tˆtƒ‰ t	‡ ‡‡fdd„t
ˆƒD ƒŽ S |jdkrš|dkršdˆd  dˆd	   d
ˆd   d S ˆd dkròtˆtƒ‰ ‡ ‡‡fdd„t
ˆd ƒD ƒ‰ t	ˆ Ž }t|ƒ\}}t|ˆ| ƒ}|S dtd| t ƒ d tj }t|ˆtƒ}|S td|  ƒ‚dS )zu
    Returns the minimal polynomial of ``sin(ex)``
    see https://mathworld.wolfram.com/TrigonometryAngles.html
    r   c                    s$   g | ]}ˆˆ| d   ˆ |  ‘qS )r;   r5   ©r7   rF   ©r]   rA   r@   r5   r9   r:   ˜  s     z _minpoly_sin.<locals>.<listcomp>r;   é	   é@   é   é`   é   é$   rL   é   c                    s    g | ]}ˆˆ|  ˆ |  ‘qS r5   r5   r©   rª   r5   r9   r:   ¢  s     r�   N)ra   Úas_coeff_Mulr   rž   Úqr   Úis_primer   r   r   rR   rc   r"   r_   r   r   rg   rŠ   r   r   )	r    r@   r—   r³   r“   rJ   rX   r”   rh   r5   rª   r9   Ú_minpoly_sin‰  s,    


(
rµ   c           	         s2  | j d  ¡ \}‰ ˆ tk�r"|j�r"|jdkr€|jdkr\dˆd  dˆd   dˆ  d S |jdkrÂdˆd  d	ˆ  d S nB|jdkrÂt|jƒ}|jrÂt| ˆƒ}t	| 
ˆtdˆ d ƒi¡ƒS t|jƒ‰tˆtƒ‰ ‡ ‡‡fd
d„tˆd ƒD ƒ‰ tˆ Ž d|j  }t|ƒ\}}t|ˆ| ƒ}|S td|  ƒ‚dS )zu
    Returns the minimal polynomial of ``cos(ex)``
    see https://mathworld.wolfram.com/TrigonometryAngles.html
    r   r;   é   é   r±   r¯   rL   r«   r­   c                    s    g | ]}ˆˆ|  ˆ |  ‘qS r5   r5   r©   rª   r5   r9   r:   Å  s     z _minpoly_cos.<locals>.<listcomp>ro   r�   N)ra   r²   r   rž   rc   r³   r   r´   rµ   r   rE   r   Úintr   r   rR   r   r"   r_   r   )	r    r@   r—   r³   r[   r“   rJ   rX   r”   r5   rª   r9   Ú_minpoly_cos¯  s*    


$





r¹   c                 C   sÜ   | j d  ¡ \}}|tkrÌ|jrÌ|d }t|jƒ}|jd dkrD|nd}g }t|jd d |d dƒD ]@}| |||  ¡ ||| d  ||   |d |d   }qft	|Ž }t
|ƒ\}}	t|	|| ƒ}
|
S td|  ƒ‚dS )zk
    Returns the minimal polynomial of ``tan(ex)``
    see https://github.com/sympy/sympy/issues/21430
    r   rL   r;   r�   N)ra   r²   r   rž   r¸   r³   rc   rR   rr   r   r"   r_   r   )r    r@   r—   r]   rA   rš   rC   r“   rJ   rX   r”   r5   r5   r9   Ú_minpoly_tanÎ  s    
,rº   c           	         s`  | j d  ¡ \}}|tt k�rP|j�rDt|jƒ}|jdksH|jdk�r|dkr`ˆ d ˆ  d S |dkrtˆ d d S |dkr�ˆ d ˆ d  d S |dkr¤ˆ d d S |d	krÀˆ d ˆ d  d S |d
krìˆ d ˆ d  ˆ d  ˆ d  d S |j�rd}t	|ƒD ]}|ˆ  | 7 }�q |S ‡ fdd„t
d| ƒD ƒ}t|ˆ | ƒ}|S td|  ƒ‚td|  ƒ‚dS )z7
    Returns the minimal polynomial of ``exp(ex)``
    r   r;   ro   r±   rL   r¯   r­   r·   r«   r<   c                    s   g | ]}t |ˆ ƒ‘qS r5   r.   r©   ©r@   r5   r9   r:     s     z _minpoly_exp.<locals>.<listcomp>r�   N)ra   r²   r	   r   rž   r   r³   rc   r´   rR   r   r_   r   )	r    r@   r—   r]   r³   r[   rF   rX   r¢   r5   r»   r9   Ú_minpoly_expæ  s6    
$r¼   c                 C   s:   | j }| | jjd |i¡}t||ƒ\}}t||| ƒ}|S )zA
    Returns the minimal polynomial of a ``CRootOf`` object.
    r   )rh   rE   Zpolyr†   r"   r_   )r    r@   rc   rJ   rX   r‚   r5   r5   r9   Ú_minpoly_rootof
  s
    r½   c              	      sˆ  | j r| j| | j S | tkrXt|d d ||d�\}}t|ƒdkrP|d d S |t S | tjkr¸t|d | d ||d�\}}t|ƒdkrœ|d | d S t||dt	dƒ d |d�S | tj
k�rPt|d |d  | d ||d�\}}t|ƒdk�r|d |d  | d S dtddt	dƒ  ƒ tddt	dƒ  ƒ d }t||||d�S t|d	ƒ�rp| |jk�rp||  S |j�r¨t| ƒ�r¨| |8 } t| ƒ}|| k�r | S |} �qŠ| j�rÆt||f| jžŽ }�n¾| j�rät| ƒj}t| ¡ d
d„ ƒ}	|	d �rÐ|tk�rÐtdd„ |	d |	d  D ƒŽ }t|	d ƒ}
dd„ |
 ¡ D ƒ}tt|dƒ‰ tj}|
  |tj!¡}‡ fdd„|
 ¡ D ƒ}t|Ž }t"||ƒ}|j|ˆ   |j||ˆ     }|| |t#dˆ ƒ  }t$t||||||d�}nt%||f| jžŽ }n | j&�r t'| j(| j)||ƒ}n„| j*t+k�rt,| |ƒ}nl| j*t-k�r0t.| |ƒ}nT| j*t/k�rHt0| |ƒ}n<| j*t)k�r`t1| |ƒ}n$| j*t2k�rxt3| |ƒ}nt4d|  ƒ‚|S )a¡  
    Computes the minimal polynomial of an algebraic element
    using operations on minimal polynomials

    Examples
    ========

    >>> from sympy import minimal_polynomial, sqrt, Rational
    >>> from sympy.abc import x, y
    >>> minimal_polynomial(sqrt(2) + 3*Rational(1, 3), x, compose=True)
    x**2 - 2*x - 1
    >>> minimal_polynomial(sqrt(y) + 1/y, x, compose=True)
    x**2*y**2 - 2*x*y - y**3 + 1

    rL   r;   r‡   r4   )rY   r±   é   é!   r=   c                 S   s   | d j o| d j S )Nr   r;   )rb   )Zitxr5   r5   r9   rl   K  rm   z"_minpoly_compose.<locals>.<lambda>Tc                 S   s   g | ]\}}|| ‘qS r5   r5   )r7   Zbxr    r5   r5   r9   r:   M  s     z$_minpoly_compose.<locals>.<listcomp>FNc                 S   s   g | ]
}|j ‘qS r5   )r³   )r7   rd   r5   r5   r9   r:   O  s     c                    s$   g | ]\}}||j ˆ  |j  ‘qS r5   )rc   r³   )r7   Úbaserd   ©Zlcmdensr5   r9   r:   S  s     )r�   r‘   r�   )5rb   r³   rc   r	   r"   rO   r   ZGoldenRatior_   r   ZTribonacciConstantr   rP   r=   Úis_QQre   r~   r`   r§   ra   rq   r   rX   r2   Úitemsr   r   ÚdictÚvaluesr   r(   ZNegativeOneÚpopZZeroÚminimal_polynomialr
   r•   r¨   rf   r¤   rÀ   r   Ú	__class__r   rµ   r   r¹   r   rº   r¼   r-   r½   r   )r    r@   rY   rJ   rX   ZfacrŽ   r”   r8   r“   Úr1ZdensZneg1Zexpn1Znumsr�   r�   r‘   r5   rÁ   r9   rŠ     sr     
&0


 rŠ   TFc           	      C   s8  t | ƒ} | jrt| dd�} t| ƒD ]}|jr"d} q6q"|dk	rNt |ƒt }}ntdƒt }}|s|| jrxt	t
t| jƒƒ}nt
}t|dƒr ||jkr td||f ƒ‚|� rþt| ||ƒ}| ¡ d }| |t||ƒ ¡}|jrât| ƒ}|rô|||dd	�S | |¡S |j�std
ƒ‚t| ||ƒ}|�r.|||dd	�S | |¡S )a-  
    Computes the minimal polynomial of an algebraic element.

    Parameters
    ==========

    ex : Expr
        Element or expression whose minimal polynomial is to be calculated.

    x : Symbol, optional
        Independent variable of the minimal polynomial

    compose : boolean, optional (default=True)
        Method to use for computing minimal polynomial. If ``compose=True``
        (default) then ``_minpoly_compose`` is used, if ``compose=False`` then
        groebner bases are used.

    polys : boolean, optional (default=False)
        If ``True`` returns a ``Poly`` object else an ``Expr`` object.

    domain : Domain, optional
        Ground domain

    Notes
    =====

    By default ``compose=True``, the minimal polynomial of the subexpressions of ``ex``
    are computed, then the arithmetic operations on them are performed using the resultant
    and factorization.
    If ``compose=False``, a bottom-up algorithm is used with ``groebner``.
    The default algorithm stalls less frequently.

    If no ground domain is given, it will be generated automatically from the expression.

    Examples
    ========

    >>> from sympy import minimal_polynomial, sqrt, solve, QQ
    >>> from sympy.abc import x, y

    >>> minimal_polynomial(sqrt(2), x)
    x**2 - 2
    >>> minimal_polynomial(sqrt(2), x, domain=QQ.algebraic_field(sqrt(2)))
    x - sqrt(2)
    >>> minimal_polynomial(sqrt(2) + sqrt(3), x)
    x**4 - 10*x**2 + 1
    >>> minimal_polynomial(solve(x**3 + x + 3)[0], x)
    x**3 + x + 3
    >>> minimal_polynomial(sqrt(y), x)
    x**2 - y

    T)Ú	recursiveFNr@   r=   z5the variable %s is an element of the ground domain %sr;   )Úfieldz!groebner method only works for QQ)r   rQ   r   r   Úis_AlgebraicNumberr   r   r    Zfree_symbolsr   r   ÚlistrP   r=   r   rŠ   r�   r€   r%   Zis_negativer   ZcollectrÂ   rW   Ú_minpoly_groebner)	r    r@   r‹   Úpolysrˆ   rh   Úclsr‚   r—   r5   r5   r9   rÇ   q  s:    7ÿ
rÇ   c                    s|  t dtd�‰i i  ‰‰d‡‡‡fdd„	‰‡ ‡‡‡‡‡fdd„‰ dd	„ }d
}t| ƒ} | jrf|  ¡  ˆ¡S | jr~| jˆ | j }nÆ|| ƒ}|r’| d } d}| j	rÂd| j
 jrÂd| j
 }t| j|ˆƒ}nt| ƒrØt| tjˆƒ}|dk	rä|}|dk�rDˆ | ƒ}ˆ| gtˆ ¡ ƒ }	t|	tˆ ¡ ƒˆg dd�}
t|
d ƒ\}}t|ˆ| ƒ}|�rxt|ˆƒ}| ˆt|ˆƒ ¡dk �rxt| ƒ}|S )a/  
    Computes the minimal polynomial of an algebraic number
    using Groebner bases

    Examples
    ========

    >>> from sympy import minimal_polynomial, sqrt, Rational
    >>> from sympy.abc import x
    >>> minimal_polynomial(sqrt(2) + 3*Rational(1, 3), x, compose=False)
    x**2 - 2*x - 1

    r]   )rÐ   Nc                    s<   t ˆ ƒ}|ˆ| < |d k	r*|| | ˆ| < n| |¡ˆ| < |S rI   )Únextr>   )r    r   rÀ   r]   )Ú	generatorÚmappingr=   r5   r9   Úupdate_mappingà  s    z)_minpoly_groebner.<locals>.update_mappingc                    sœ  | j r<| tjkr.| ˆkr$ˆ| ddƒS ˆ|  S n
| jr8| S �nP| jrZt‡ fdd„| jD ƒŽ S | jrxt‡ fdd„| jD ƒŽ S | j	�rd| j
j�rŒ| j
dk ràt| jˆˆƒ}tˆ|ƒ ¡ }| ˆ| j¡ ¡ }| j
dkrÔˆ |ƒS || j
  } | j
j�s| j| j
j  ¡ td| j
jƒ }}n| j| j
 }}ˆ |ƒ}|| }|ˆk�rZ|j�rF| ¡ S ˆ|d| | ƒS nˆ| S n(| j�rŒ| ˆk�r„ˆ| |  ¡ ƒS ˆ|  S td|  ƒ‚d	S )
aÓ  
        Transform a given algebraic expression *ex* into a multivariate
        polynomial, by introducing fresh variables with defining equations.

        Explanation
        ===========

        The critical elements of the algebraic expression *ex* are root
        extractions, instances of :py:class:`~.AlgebraicNumber`, and negative
        powers.

        When we encounter a root extraction or an :py:class:`~.AlgebraicNumber`
        we replace this expression with a fresh variable ``a_i``, and record
        the defining polynomial for ``a_i``. For example, if ``a_0**(1/3)``
        occurs, we will replace it with ``a_1``, and record the new defining
        polynomial ``a_1**3 - a_0``.

        When we encounter a negative power we transform it into a positive
        power by algebraically inverting the base. This means computing the
        minimal polynomial in ``x`` for the base, inverting ``x`` modulo this
        poly (which generates a new polynomial) and then substituting the
        original base expression for ``x`` in this last polynomial.

        We return the transformed expression, and we record the defining
        equations for new symbols using the ``update_mapping()`` function.

        rL   r;   c                    s   g | ]}ˆ |ƒ‘qS r5   r5   ©r7   ry   ©Úbottom_up_scanr5   r9   r:     s     z=_minpoly_groebner.<locals>.bottom_up_scan.<locals>.<listcomp>c                    s   g | ]}ˆ |ƒ‘qS r5   r5   rÕ   rÖ   r5   r9   r:     s     r   ro   z*%s does not seem to be an algebraic numberN)rt   r   ZImaginaryUnitrb   r`   r   ra   rq   r   rf   r   rÎ   rÀ   r!   r>   rE   Úexpandr   rc   r
   r³   rÌ   Úminpoly_of_elementr   )r    Zminpoly_baseZinverseZbase_invrÀ   r   rh   )r×   rÐ   rÓ   r=   rÔ   r@   r5   r9   r×   ë  sJ    





 ÿ


z)_minpoly_groebner.<locals>.bottom_up_scanc                 S   st   | j r(d| j jr(| jdk r(| jjr(dS | jrpd}| jD ].}|jrH dS |j r8|jjr8|jdkr8 dS q8|rpdS dS )z
        Returns True if it is more likely that the minimal polynomial
        algorithm works better with the inverse
        r;   r   TF)rf   r   ru   rÀ   r`   rq   ra   )r    Úhitrc   r5   r5   r9   Úsimpler_inverse5  s    
z*_minpoly_groebner.<locals>.simpler_inverseFro   r;   Úlex)Úorderr   )N)r0   r   r   rÌ   rÙ   r>   rb   r³   rc   rf   r   r   rƒ   rÀ   re   r   rs   rÍ   rÅ   r#   r"   r_   r›   r€   r%   r   )r    r@   rÐ   rÛ   Úinvertedr‚   r”   rA   Úbusrx   ÚGrJ   rX   r5   )r×   rÐ   rÒ   rÓ   r=   rÔ   r@   r9   rÎ   Î  sB    
J



rÎ   c                 C   s   t | ||||d�S )z6This is a synonym for :py:func:`~.minimal_polynomial`.)r@   r‹   rÏ   rˆ   )rÇ   )r    r@   r‹   rÏ   rˆ   r5   r5   r9   Úminpolyp  s    rá   )NN)N)NTFN)NTFN)]Ú__doc__Ú	functoolsr   Zsympy.core.addr   Zsympy.core.exprtoolsr   Zsympy.core.functionr   r   r   Zsympy.core.mulr   Zsympy.core.numbersr	   r
   r   r   Zsympy.core.singletonr   Zsympy.core.symbolr   Zsympy.core.sympifyr   Zsympy.core.traversalr   Z&sympy.functions.elementary.exponentialr   Z(sympy.functions.elementary.miscellaneousr   r   Z(sympy.functions.elementary.trigonometricr   r   r   Zsympy.ntheory.factor_r   Zsympy.utilities.iterablesr   Zsympy.polys.domainsr   r   r   Zsympy.polys.orthopolysr   Zsympy.polys.polyerrorsr   r   Zsympy.polys.polytoolsr   r    r!   r"   r#   r$   r%   r&   r'   r(   Zsympy.polys.polyutilsr)   r*   Zsympy.polys.ring_seriesr+   Zsympy.polys.ringsr,   Zsympy.polys.rootoftoolsr-   Zsympy.polys.specialpolysr/   Zsympy.utilitiesr0   r1   r2   r_   re   r~   rƒ   r•   r›   rŒ   r¤   r§   r¨   rµ   r¹   rº   r¼   r½   rŠ   rÇ   rÎ   rá   r5   r5   r5   r9   Ú<module>   s^   00A6
O
5&$\\ #