
    EdBl                     4   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ZJd ZKd ZLd  ZMd3d"ZNd# ZOd$ ZPd4d%ZQd& ZRd' ZSd( ZTd) ZUd* ZVd+ ZWd, ZXd- ZYeHd5d0            ZZd1 Z[eHd5d2            Z\d!S )6z*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                    t          | d         t                    rd | D             } t          |           dk    r| d         S di t          |d          r|j        ng }k    rfd| D             }j        rfd|D             }t          t          |          t          |          d	          D ]}t          ||          D ]
\  }	}
|
|	<   fd
t          |          D             }t          d |D                       rSt          |          }|dd         \  \  }}\  }}||dz  k    r
| |         c S dz  k    t          dz            )ze
    Return a factor having root ``v``
    It is assumed that one of the factors has root ``v``.
    r   c                     g | ]
}|d          S )r    ).0fs     @lib/python3.11/site-packages/sympy/polys/numberfields/minpoly.py
<listcomp>z"_choose_factor.<locals>.<listcomp>/   s    )))A1Q4)))       
   symbolsc                 b    g | ]+}|                                                     i          ,S r8   )as_exprxreplace)r9   r:   vxs     r;   r<   z"_choose_factor.<locals>.<listcomp>9   s3    ;;;aaiikk""Aa5));;;r=   c                 :    g | ]}|                               S r8   )n)r9   r:   precs     r;   r<   z"_choose_factor.<locals>.<listcomp>;   s#    (((!##d))(((r=   T)k
repetitionc                     g | ]<\  }}t          |                                                                      |f=S r8   )abssubsrG   )r9   ir:   pointsprec1s      r;   r<   z"_choose_factor.<locals>.<listcomp>C   sR     * * *Aa qvvf~~//6677; * * *r=   c              3   .   K   | ]\  }}|t           v V  d S N)r   )r9   rN   _s      r;   	<genexpr>z!_choose_factor.<locals>.<genexpr>H   s*      88TQ1=888888r=   N   i@B z4multiple candidates for the minimal polynomial of %s)
isinstancetuplelenhasattrr@   	is_numberr   rangezip	enumerateanysortedNotImplementedError)factorsrE   rD   domrH   boundr@   ferG   srN   
candidatescanaixbrS   rO   rP   s    `` `            @@r;   _choose_factorrk   (   s    '!*e$$ *)))))
7||q qzEF$S)44<ckk"G
4-  <;;;;7;;;; 	)((((R(((B uW$GGG 	# 	#AGQ  1q		* * * * *$R==* * *J
 88Z88888 
 $$C!"1"gOGQVa1u9} #r{"""# 	
; 4- > TWXX
Y
YYr=   c                 Z    | j         r| j        n| g}|D ]}|dz  j        r|j        s dS dS )NrU   FT)is_Addargsis_Rationalis_extended_real)prn   ys      r;   _is_sum_surdsrs   X   sO    X&166A3D  A" 	q'9 	55	4r=   c                 
   d }g }| j         D ]}|j        s ||          r%|                    t          j        |dz  f           9|j        r"|                    |t          j        f           b|j        r.|j        j        r"|                    |t          j        f           t          t          |j         |d          \  }}|                    t          | t          | dz  f           |                    d            |d         d         t          j        u r| S d	 |D             }t          t          |                    D ]}||         dk    r nd
dlm}  |||d          \  }	}
}g }g }|D ]T\  }}||
v r&|                    ||t          j        z  z             /|                    ||t          j        z  z             Ut%          | }t%          | }t'          |dz            t'          |dz            z
  } | 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                 6    | j         o| j        t          j        u S rR   )is_Powr   r   Half)exprs    r;   is_sqrtz_separate_sq.<locals>.is_sqrtz   s    {1tx1611r=   rU   T)binaryc                     | d         S )Nr>   r8   )zs    r;   <lambda>z_separate_sq.<locals>.<lambda>   s
    1 r=   )keyr>   c                     g | ]\  }}|S r8   r8   )r9   rr   r|   s      r;   r<   z _separate_sq.<locals>.<listcomp>   s    41aQr=   r   )
_split_gcdN)rn   is_Mulappendr   Oneis_Atomrv   r   
is_integerr`   r3   r	   sortr[   rX   sympy.simplify.radsimpr   rw   r   r   )rq   ry   rh   rr   TFsurdsrN   r   gb1b2a1a2r|   p1p2s                    r;   _separate_sqr   `   sB   42 2 2 	AV , ,x 	,wqzz *!%A'''' *!QU$$$$ *ae. *!QU$$$$))555DAqHHc1gsAwz*++++FF~~FuQx15 1E3u::  8q= 	E	111111
E!""I&IAr2	B	B # #17 	#IIa16	k""""IIa16	k""""	bB	bBQ(2q5//)AHr=   c                 $   t          |           } t          |          }|j        r|dk    rt          |           sdS | t          d|          z  }| |z  } 	 t	          |           }|| u r|                    |||z  i          } n|} 1|dk    r]t          |           }|                     ||                    |          z            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_Integerrs   r   r   rM   r    coeffr&   	primitiver#   rk   )rq   rG   rE   pnr   ra   results          r;   _minimal_polynomial_sqr      s&   . 	

A

A< q1u M!,<,< t	
HQNN	BFA!__7 	1a4!!AA 	Av !WW771biill?##a' 	AKKMM! !nnQGGQ++FMr=   Nc                 >   t          t          |                    }|t          |||          }|t          |||          }n|                    ||i          }| t          u r|t
          k    rUt          dt
                    \  }}	 |t          |          d                   }
 |t          |          d                   }npt          |||z
  f||          \  \  }
}}|
	                    |          }|
                                }n*| t          u rt          |||          }nt          d          | t          u s|t
          k    rt          ||||g          }n2t          |
|          }t!          |                                |          }t%          ||          }t%          ||          }| t          u r|dk    s|dk    r|S t'          |||          }|                                \  }}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_composerM   r   r   r-   r*   r(   composerB   r	   _mulyr`   r%   r,   r+   as_expr_dictr&   r    r#   rk   )opex1ex2rE   rb   mp1mp2rr   Rr   r   r   rS   rmp1adeg1deg2ra   ress                      r;   _minpoly_op_algebraic_elementr      s   H 	c!ffA
 ,sAs++
 sAs++hh1v	Sy :"9 	R==DAq>#&&q)**B>#&&q)**BB13A,1EEKHRa

2A99;;DD	s :S!Q!"8999	Sy 0C2I 0dCq!f---2r""1>>++Q//#q>>D#q>>D	Sy TQY $!)  Q#AJAw
!RRS\\3
7
7C;;==r=   c                     t          |           d         }t          |          fd|                                D             }t          | S )z@
    Returns ``expand_mul(x**degree(p, x)*p.subs(x, 1/x))``
    r   c                 0    g | ]\  \  }}||z
  z  z  S r8   r8   )r9   rN   crG   rE   s      r;   r<   z_invertx.<locals>.<listcomp>-  s+    222GDQ!QQZ222r=   r'   r&   termsr   )rq   rE   r   rh   rG   s    `  @r;   _invertxr   &  sR     
1		a	 Br

A22222rxxzz222A7Nr=   c                     t          |           d         }t          |          fd|                                D             }t          | S )z8
    Returns ``_mexpand(y**deg*p.subs({x:x / y}))``
    r   c                 <    g | ]\  \  }}||z  z  |z
  z  z  S r8   r8   )r9   rN   r   rG   rE   rr   s      r;   r<   z_muly.<locals>.<listcomp>8  s4    99974AQTAAJ	999r=   r   )rq   rE   rr   r   rh   rG   s    ``  @r;   r   r   1  sV     
1		a	 Br

A999999bhhjj999A7Nr=   c                 `   t          |          }|st          | ||          }|j        st          d| z            |dk     r8||k    rt	          d| z            t          ||          }|dk    r|S | }d| z  } t          t          |                    }|                    ||i          }|	                                \  }}t          t          |||z  ||z  z
  |g          ||          }|                                \  }	}
t          |
|| |z  |          }|                                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 zeror   r>   r   r   )r   r   is_rationalr   ZeroDivisionErrorr   r   r   rM   as_numer_denomr    r%   r#   rk   rB   )expwrE   rb   mprr   rG   dr   rS   ra   s              r;   _minpoly_powr   <  sB   < 
B *b!S))> OH2MNNN	Av 7 	7#L2$5666b!__8 	ISrTc!ffA	!QBDAq
yQTAqD[s333Qs
C
C
CC""JAw
!RVS
1
1C;;==r=   c           	          t          t          |d         |d         | |          }|d         |d         z   }|dd         D ]!}t          t          ||| ||          }||z   }"|S )z.
    returns ``minpoly(Add(*a), dom, x)``
    r   r>   rU   Nr   )r   r   rE   rb   rh   r   rq   pxs         r;   _minpoly_addr   q  s     
'sAaD!A$3	?	?B	!qtAe  *32q#2FFFFIr=   c           	          t          t          |d         |d         | |          }|d         |d         z  }|dd         D ]!}t          t          ||| ||          }||z  }"|S )z.
    returns ``minpoly(Mul(*a), dom, x)``
    r   r>   rU   Nr   )r   r	   r   s         r;   _minpoly_mulr   }  r   r=   c                   	
 | j         d                                         \  }		t          u r=|j        r5|j        
t          
          }|j        r9t          
t                    	t          	
fdt          
          D              S |j        dk    r#|dk    rddz  z  ddz  z  z
  d	d
z  z  z   dz
  S 
d
z  dk    rct          
t                    		
fdt          
dz             D             	t          	 }t          |          \  }}t          ||           }|S dt          d
|z  t          z            z
  d
z  t          j        z  }t#          |t$                    }|S t'          d| z            )zt
    Returns the minimal polynomial of ``sin(ex)``
    see http://mathworld.wolfram.com/TrigonometryAngles.html
    r   c                 8    g | ]}|z
  d z
  z  |         z  S )r>   r8   r9   rN   rh   rG   rE   s     r;   r<   z _minpoly_sin.<locals>.<listcomp>  s.    CCCQQQ^AaD0CCCr=   r>   	   @      `      $   rU      c                 2    g | ]}|z
  z  |         z  S r8   r8   r   s     r;   r<   z _minpoly_sin.<locals>.<listcomp>  s)    ;;;QQZ!_;;;r=   r   )rn   as_coeff_Mulr   r   qr   is_primer   r   r   r[   rq   r#   rk   r   r   rw   r   r   r   )r   rE   r   r   r   rS   ra   r   rx   rh   rG   s    `       @@r;   _minpoly_sinr     s   
 71:""$$DAqBw = 	A

Az E #1b))CCCCCC%((CCCDDsax ;6 ;ad7R1W,r!Q$w6::1uz 	 #1b));;;;;;eAEll;;;G(^^
7$Wa44
QqSV_a'!&0D"4B//CJ
DrI
J
JJr=   c           	        	
 | j         d                                         \  }		t          u rD|j        r<|j        dk    rB|j        dk    rddz  z  ddz  z  z
  dz  z
  dz   S |j        dk    rddz  z  d	z  z
  dz
  S nm|j        dk    rbt          |j                  }|j        rGt          |           }t          |
                    t          dz
  dz            i                    S t          |j                  
t          
t                    		
fd
t          
dz             D             	t!          	 d|j        z  z
  }t#          |          \  }}t%          ||           }|S t'          d| z            )zt
    Returns the minimal polynomial of ``cos(ex)``
    see http://mathworld.wolfram.com/TrigonometryAngles.html
    r   r>         r   r   rU   r   r   c                 2    g | ]}|z
  z  |         z  S r8   r8   r   s     r;   r<   z _minpoly_cos.<locals>.<listcomp>  s)    777QQUAaD777r=   r   r   )rn   r   r   r   rq   r   r   r   r   r   rM   r   intr   r   r[   r   r#   rk   r   )r   rE   r   r   re   r   rS   ra   r   rh   rG   s    `       @@r;   _minpoly_cosr     s   
 71:""$$DAqBw = 	sax 	A3!8 5QT6AadF?QqS01443!8 ,QT6AaC<!++, AACLL: A$R++A#AFFAdAE19oo+>$?$?@@@ ACAq"%%A777777%A,,777AQ2)#A$QJAw !R00CJ
DrI
J
JJr=   c                    | j         d                                         \  }}|t          u r|j        r|dz  }t	          |j                  }|j        dz  dk    r|nd}g }t          |j        dz   dz  |dz   d          D ];}|                    |||z  z             |||z
  dz
  z  ||z
  z   |dz   |dz   z  z  }<t          | }t          |          \  }}	t          |	||           }
|
S t          d| z            )zk
    Returns the minimal polynomial of ``tan(ex)``
    see https://github.com/sympy/sympy/issues/21430
    r   rU   r>   r   )rn   r   r   r   r   r   rq   r[   r   r   r#   rk   r   )r   rE   r   rh   rG   r   rI   r   rS   ra   r   s              r;   _minpoly_tanr     s   
 71:""$$DAqBw = 	AAACAS1W\(qAEACE19ac1-- 8 8Qq!tV$$$1Qi1o&AaC!A#;7UA$QJAw !R00CJ
DrI
J
JJr=   c                    | j         d                                         \  }}|t          t          z  k    r|j        rt          |j                  }|j        dk    s|j        dk    r|dk    rdz  z
  dz   S |dk    rdz  dz   S |dk    rdz  dz  z
  dz   S |dk    rdz  dz   S |d	k    rdz  dz  z
  dz   S |d
k    rdz  dz  z
  dz  z   dz  z
  dz   S |j        rd}t          |          D ]}| |z  z  }|S fdt          d|z            D             }t          ||           }|S t          d| z            t          d| z            )z7
    Returns the minimal polynomial of ``exp(ex)``
    r   r>   r   r   rU   r   r   r   r   r?   c                 0    g | ]}t          |          S r8   r/   )r9   rN   rE   s     r;   r<   z _minpoly_exp.<locals>.<listcomp>  s#    DDDq!,,DDDr=   r   )rn   r   r
   r   r   r   r   rq   r   r[   r   rk   r   )	r   rE   r   rh   r   re   rN   ra   r   s	    `       r;   _minpoly_expr     s    71:""$$DAqAbDy S= 	SAsax 13"9 6 (a4!8a<'6 $a4!8O6 +a4!Q$;?*6 $a4!8O6 +a4!Q$;?*7 9a4!Q$;A-14q88: A"1XX % %qb1WH EDDDhqsmmDDDGB//BILrQRRR
DrI
J
JJr=   c                     | j         }|                    | j        j        d         |i          }t	          ||          \  }}t          |||           }|S )zA
    Returns the minimal polynomial of a ``CRootOf`` object.
    r   )rx   rM   polyr   r#   rk   )r   rE   rq   rS   ra   r   s         r;   _minpoly_rootofr   
  sR     	A	Q"##AQ""JAwGQ++FMr=   c           	         | j         r| j        |z  | j        z
  S | t          u r@t	          |dz  dz   ||          \  }}t          |          dk    r|dz  dz   n	|t          z
  S | t          j        u rbt	          |dz  |z
  dz
  ||          \  }}t          |          dk    r|dz  |z
  dz
  S t          ||dt          d          z   dz  |          S | t          j
        u rt	          |dz  |dz  z
  |z
  dz
  ||          \  }}t          |          dk    r|dz  |dz  z
  |z
  dz
  S dt          ddt          d          z  z
            z   t          ddt          d          z  z             z   dz  }t          ||||          S t          |d	          r| |j        v r|| z
  S |j        r-t          |           r| |z  } 	 t!          |           }|| u r| S |} | j        rt%          ||g| j        R  }n\| j        rt+          |           j        }t/          |                                d
           }	|	d         r/|t2          k    r#t5          d |	d         |	d         z   D              }t7          |	d                   }
d |
                                D             }t;          t<          |d          t          j        }|
                     |t          j!                  }fd|
                                D             }t5          | }tE          ||          }|j        |z  z  |j        ||z  z  z  z
  }||z  |tG          d          z  z  }tI          t4          ||||||          }ntK          ||g| j        R  }n| j&        rtO          | j(        | j)        ||          }n| j*        tV          u rtY          | |          }n| j*        tZ          u rt]          | |          }no| j*        t^          u rta          | |          }nP| j*        tR          u rtc          | |          }n1| j*        td          u rtg          | |          }nti          d| z            |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

    rU   r>   r   r5   )rb   r      !   r@   c                 6    | d         j         o| d         j         S )Nr   r>   )ro   )itxs    r;   r}   z"_minpoly_compose.<locals>.<lambda>K  s    A(:(Qs1v?Q r=   Tc                     g | ]
\  }}||z  S r8   r8   )r9   bxr   s      r;   r<   z$_minpoly_compose.<locals>.<listcomp>M  s     @@@62rB@@@r=   FNc                     g | ]	}|j         
S r8   )r   )r9   rr   s     r;   r<   z$_minpoly_compose.<locals>.<listcomp>O  s    ---AAC---r=   c                 @    g | ]\  }}||j         z  |j        z  z  S r8   )rq   r   )r9   baserr   lcmdenss      r;   r<   z$_minpoly_compose.<locals>.<listcomp>S  s/    III74D13w;!#-.IIIr=   )r   r   r   )5ro   r   rq   r
   r#   rX   r   GoldenRatiork   r   TribonacciConstantr   rY   r@   is_QQrs   r   rm   r   rn   r   r   ra   r3   itemsr   r	   dictvaluesr   r)   NegativeOnepopZerominimal_polynomialr   r   r   rv   r   r   r   	__class__r   r   r   r   r   r   r   r.   r   r   )r   rE   rb   rS   ra   facr   r   r:   r   r1densneg1expn1numsr   r   r   r   s                     @r;   r   r     s     
~ tAv}	Qw 8 A1S999
7w<<1,7q!taxx!a%7	Q] H AAq===
7w<<1 	Ha4!8a<!'1q477{Ao3GGGG	Q!! < A1q1!4aDDD
7w<<1 	<a4!Q$;?Q&&tB488O,,,tB488O/D/DDIC!'1cs;;;;sI 2#4 2v
y ]2&& 
a	r""Cby 		 
y &O1c,BG,,,	 $OBKKQQRRT7 	1sby 	1@@QuX$-?@@@ACagB-----DS$**G=DFF4((EIIIIbhhjjIIIDt*C$S!,,C %7
"SU4%-+@%@@C+Xa%9%9 99C/S#q#3TWXXXCCq#0000CC	 O27BFAs33		 O2q!!		 	O2q!!		 O2q!!		 O2q!!		  Ob!$$H2MNNNJr=   TFc                 j   t          |           } | j        rt          | d          } t          |           D ]}|j        rd} n|t          |          t
          }}nt          d          t          }}|s6| j        r(t          t          t          | j                            }nt          }t          |d          r||j        v rt          d|d|          |rt          | ||          }|                                d	         }|                    |t%          ||          z            }|j        rt)          |           }|r |||d
          n|                    |          S |j        st/          d          t1          | ||          }|r |||d
          n|                    |          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)	recursiveFNrE   r@   zthe variable z$ is an element of the ground domain r>   )fieldz!groebner method only works for QQ)r   rZ   r   r   is_AlgebraicNumberr    r   r!   free_symbolsr   r   listrY   r@   r   r   r   r   r&   is_negativer   collectr   r`   _minpoly_groebner)	r   rE   r   polysr   rx   clsr   r   s	            r;   r   r   q  s   n 
B	| *bD)))"2&&  " 	GE	 	 &T3sX3 ? 	"2tBO'<'<==FFFvy!! 9a6>&9 9o-.QQ8 9 9 	9  J!"a00!!##A&LLF61---..= 	)((F-2Iss61D))))q8I8II< G!"EFFFr1c**F).E33vq%%%%FNN14E4EEr=   c                    t          dt                    i i cdfd	fdd }d}t          |           } | j        r'|                                                               S | j        r| j        z  | j        z
  }n ||           }|r| dz  } d}| j	        r0d	| j
        z  j        r!d	| j
        z  }t          | j        |          }n*t          |           rt          | t          j                  }||}| |           }|z
  gt#                                                    z   }	t'          |	t#                                                    gz   d
          }
t)          |
d                   \  }}t+          ||           }|rJt-          |          }|                    t1          |          z            dk     rt3          |           }|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

    rh   )r  Nc                 r    t                    }|| <   |||z  |z   | <   n |j        |          | <   |S rR   )nextrB   )r   r   r   rh   	generatormappingr@   s       r;   update_mappingz)_minpoly_groebner.<locals>.update_mapping  sJ    OO 	)S&4-GBKK%#+a..GBKr=   c                    | j         r2| t          j        u r| 	vr | dd          S 
|          S | j        r| S n| j        rt          fd| j        D              S | j        rt          fd| j        D              S | j	        rB| j
        j        r4| j
        dk     rt          | j                  }t          |                                          }|                    | j                                                  }| j
        dk    r |          S || j
         z  } | j
        j        sA| j        | j
        j        z                                  t'          d| j
        j                  }}n| j        | j
        }} |          }||z  }|	vr,|j        r|                                S  |d|z  |           S 
|         S n1| j        r*| 	vr | |                                           S 
|          S t/          d| z            )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.

        rU   r>   c                 &    g | ]} |          S r8   r8   r9   r   bottom_up_scans     r;   r<   z=_minpoly_groebner.<locals>.bottom_up_scan.<locals>.<listcomp>  #    >>>..++>>>r=   c                 &    g | ]} |          S r8   r8   r  s     r;   r<   z=_minpoly_groebner.<locals>.bottom_up_scan.<locals>.<listcomp>  r  r=   r   r   z*%s does not seem to be an algebraic number)r   r   ImaginaryUnitro   rm   r   rn   r   r	   rv   r   r  r   r"   rB   rM   expandr   rq   r   r   r  minpoly_of_elementr   )r   minpoly_baseinversebase_invr   r   rx   r  r  r  r@   r  rE   s          r;   r  z)_minpoly_groebner.<locals>.bottom_up_scan  s]   8 : *	#Q_$ W$ ')>"a333"2;& 	Y "	#>>>>RW>>>??Y  	#>>>>RW>>>??Y 	#v! )6A: 1#4RWa#E#EL$Q55==??G&||Arw77>>@@Hv| 1-~h777%0v( 0)6688Xa5J5J DD !##D%~d++Syw& )~ D#{{}},-~dAGdUCCC"4=(1)2 " 	#  #%~b"*?*?*A*ABBBr{"G"LMMMr=   c                     | j         r(d| j        z  j        r| j        dk     r| j        j        rdS | j        r;d}| j        D ]-}|j        r dS |j         r|j        j        r|j        dk    r dS .|rdS dS )z
        Returns True if it is more likely that the minimal polynomial
        algorithm works better with the inverse
        r>   r   TF)rv   r   r   r   rm   r   rn   )r   hitrq   s      r;   simpler_inversez*_minpoly_groebner.<locals>.simpler_inverse5  s    
 9 	 "&$  !  7>  49 
	CW % %8 ! 558 %v} % %$uu tur=   Fr   r>   lex)orderr   rR   )r1   r   r   r  r  rB   ro   r   rq   rv   r   r   r   r   rs   r   r   r
  r   r$   r#   rk   r   r   r&   r   )r   rE   r  r$  invertedr   r   rG   busr   GrS   ra   r  r  r  r@   r  s    ``          @@@@@r;   r  r    sq    !%000I2GW	 	 	 	 	 	 	 	HN HN HN HN HN HN HN HN HN HNT  , H	B		B	 4$$&&..q111	 4a"$"?2&& 	RB9 	7!BF(. 	7"&A(!Q77CC2 	7(QUA66C 	F 	4 .$$CS	D!1!1222AD!1!122aS8FFFA$QrU++JAw#GQ33F )&!$$<<6&!,,,--1 	)((FMr=   c                 *    t          | ||||          S )z6This is a synonym for :py:func:`~.minimal_polynomial`.)rE   r   r  r   )r   )r   rE   r   r  r   s        r;   minpolyr+  p  s     bAweFSSSSr=   )NNrR   )NTFN)]__doc__	functoolsr   sympy.core.addr   sympy.core.exprtoolsr   sympy.core.functionr   r   r   sympy.core.mulr	   sympy.core.numbersr
   r   r   r   sympy.core.singletonr   sympy.core.symbolr   sympy.core.sympifyr   sympy.core.traversalr   &sympy.functions.elementary.exponentialr   (sympy.functions.elementary.miscellaneousr   r   (sympy.functions.elementary.trigonometricr   r   r   sympy.ntheory.factor_r   sympy.utilities.iterablesr   sympy.polys.domainsr   r   r   sympy.polys.orthopolysr   sympy.polys.polyerrorsr   r   sympy.polys.polytoolsr    r!   r"   r#   r$   r%   r&   r'   r(   r)   sympy.polys.polyutilsr*   r+   sympy.polys.ring_seriesr,   sympy.polys.ringsr-   sympy.polys.rootoftoolsr.   sympy.polys.specialpolysr0   sympy.utilitiesr1   r2   r3   rk   rs   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r+  r8   r=   r;   <module>rF     sA   0 0             ( ( ( ( ( ( H H H H H H H H H H       : : : : : : : : : : : : " " " " " " # # # # # # & & & & & & 3 3 3 3 3 3 6 6 6 6 6 6 ? ? ? ? ? ? ? ? B B B B B B B B B B * * * * * * - - - - - - 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1                               A @ @ @ @ @ @ @ 2 2 2 2 2 2 " " " " " " + + + + + + 4 4 4 4 4 4         
 ')s! -Z -Z -Z -Z`  ? ? ?B4 4 4lL L L L^    2 2 2 2j	 	 		 	 	#K #K #KLK K K>K K K0!K !K !KH  Y Y Yx YF YF YF YFx_ _ _D T T T T T Tr=   