B
    [j                 @   s  d Z ddlmZmZ ddlmZmZmZmZm	Z	m
Z
mZ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mZmZmZmZmZmZ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*m+Z+ ddl,m-Z-m.Z. ddl/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6 ddl7m8Z8m9Z9m:Z:m;Z;m<Z< ddl=m>Z> ddl?m@Z@ ddlAmBZB ddlCmDZD ddlEmFZF ddlGmHZH ddlImJZJmKZK ddlLmMZM ddlLmNZN e.ddfddZOdd ZPd d! ZQdRd#d$ZRd%d& ZSd'd( ZTdSd)d*ZUd+d, ZVd-d. ZWd/d0 ZXd1d2 ZYd3d4 ZZd5d6 Z[d7d8 Z\e;dTd;d<Z]d=d> Z^e]Z_e`ad? d@dA Zbe;dUdBdCZcdDdE ZddFdG ZedHdI Zfe;dJdK Zge;dVdLdMZhG dNdO dOe6Zie;dWdPdQZjd"S )Xz&Computational algebraic field theory.     )print_functiondivision)
SRationalAlgebraicNumberAddMulsympifyDummy
expand_mulIpi)exp)cossin)PolyPurePolysqf_norminvertfactor_listgroebner	resultantdegreepoly_from_exprparallel_poly_from_exprlcm)IsomorphismFailedCoercionFailedNotAlgebraicGeneratorsError)CRootOf)cyclotomic_poly)dict_from_exprexpr_from_dict)ZZQQ)dup_chebyshevt)ring)rs_compose_add)LambdaPrinter)numbered_symbols
variationslambdifypublicsift)Factors)_mexpand)
_split_gcd)_is_sum_surds)sieve)divisors)pslqmp)reduce)range      c             C   s  t | d trdd | D } t| dkr0| d S ||i}t|drH|jng }tdd}xt|t| D ]}	d}
|	}x |D ]}|| ||< || }qzW xrg }||
d  }x.| D ]&}t| 	|
||k r|
| qW |r|} t| dkr| d S |
|krP |
d9 }
qW qhW t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fr;   r;   7lib/python3.7/site-packages/sympy/polys/numberfields.py
<listcomp>?   s    z"_choose_factor.<locals>.<listcomp>   symbols
      z4multiple candidates for the minimal polynomial of %sN)
isinstancetuplelenhasattrrA   r%   r8   absas_exprevalfappendNotImplementedError)factorsxvdomZprecZboundZpointsrA   tnZprec1Zn_tempsZ
candidatesepsr=   r;   r;   r>   _choose_factor9   s6    


rU   c             C   s  ddl m} dd }g }x| jD ]}|js||rH|tj|d f q |jr`||tjf q |jr|j	j
r||tjf q tq ||j|dd\}}|t| t| d f q W |jdd	 d
 |d d tjkr| S dd |D }x"tt|D ]}|| dkrP qW t||d  \}	}
}g }g }xF|D ]>\}}||
kr\|||tj   n|||tj   q4W t| }t| }t|d t|d  } | S )a7  
    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 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

    r   )r.   c             S   s   | j o| jtjkS )N)is_Powr   r   Half)exprr;   r;   r>   is_sqrtz   s    z_separate_sq.<locals>.is_sqrtrC   T)Zbinaryc             S   s   | d S )Nr@   r;   )zr;   r;   r>   <lambda>   s    z_separate_sq.<locals>.<lambda>)keyr@   c             S   s   g | ]\}}|qS r;   r;   )r<   yrZ   r;   r;   r>   r?      s    z _separate_sq.<locals>.<listcomp>N)Zsympy.utilities.iterablesr.   argsis_MulrK   r   Oneis_AtomrV   r   
is_integerrL   r   sortr8   rF   r1   rW   r   r0   )pr.   rY   ar^   TFZsurdsigZb1Zb2Za1Za2rZ   p1p2r;   r;   r>   _separate_sq_   sB    
rm   c       	      C   s   ddl m} t| } t|}|| }|jr:|dkr:|| s>dS | td| }| |8 } x.t| }|| kr||||| i} P qV|} qVW |dkrt| }| ||	| 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 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   )r2   Nr@   )sympy.simplify.simplifyr2   r	   
is_Integerr   rm   subsr   coeffr   	primitiver   rU   )	re   rR   rN   r2   rZpnrk   rM   resultr;   r;   r>   _minimal_polynomial_sq   s.    ru   Nc             C   sz  t t|}|dkr t|||}|dkr6t|||}n|||i}| tkr|tkrtdt\}}	|t|d }
|t|d }qt||| f||\\}
}}|
	|}|
 }n| tkrt|||}ntd| tks|tkrt||||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 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] http://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_composerp   r   r%   r'   r"   r   composerI   r   _mulyrL   r   r(   r#   Zas_expr_dictr   r   r   rU   )opex1ex2rN   rP   mp1mp2r^   Rrv   rk   rl   _rs   Zmp1aZdeg1Zdeg2rM   resr;   r;   r>   _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 r;   r;   )r<   ri   c)rR   rN   r;   r>   r?   .  s    z_invertx.<locals>.<listcomp>)r   r   termsr   )re   rN   rk   rf   r;   )rR   rN   r>   _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 r;   r;   )r<   ri   r   )rR   rN   r^   r;   r>   r?   9  s    z_muly.<locals>.<listcomp>)r   r   r   r   )re   rN   r^   rk   rf   r;   )rR   rN   r^   r>   r|   2  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 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

    z*%s doesn't seem to be an algebraic elementr   z
%s is zeror]   r@   )rw   )rx   )r	   rz   is_rationalr   ZeroDivisionErrorr   r
   ry   rp   Zas_numer_denomr   r   r   rU   rI   )exZpwrN   rP   r6   r^   rR   dr   r   rM   r;   r;   r>   _minpoly_pow=  s(    
&r   c          	   G   s^   t t|d |d | |}|d |d  }x0|dd D ] }t t||| ||d}|| }q6W |S )z.
    returns ``minpoly(Add(*a), dom, x)``
    r   r@   rC   N)r   )r   r   )rN   rP   rf   r6   re   pxr;   r;   r>   _minpoly_addr  s    r   c          	   G   s^   t t|d |d | |}|d |d  }x0|dd D ] }t t||| ||d}|| }q6W |S )z.
    returns ``minpoly(Mul(*a), dom, x)``
    r   r@   rC   N)r   )r   r   )rN   rP   rf   r6   re   r   r;   r;   r>   _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rdd  dd	   d
d   d S d dkrt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 )zt
    Returns the minimal polynomial of ``sin(ex)``
    see http://mathworld.wolfram.com/TrigonometryAngles.html
    r   c                s$   g | ]}| d    |  qS )r@   r;   )r<   ri   )rf   rR   rN   r;   r>   r?     s    z _minpoly_sin.<locals>.<listcomp>r@   	   @      `      $   rC      c                s    g | ]}|   |  qS r;   r;   )r<   ri   )rf   rR   rN   r;   r>   r?     s    z*%s doesn't seem to be an algebraic elementN)r_   as_coeff_Mulr   r   qr	   is_primer&   r$   r   r8   re   r   rU   r   r   rW   rz   r%   r   )	r   rN   r   r   rs   r   rM   r   rX   r;   )rf   rR   rN   r>   _minpoly_sin  s,    


(
r   c       
         s>  ddl m} | jd  \}  tkr.|jr.|jdkr|jdkrhdd  dd   d  d S |jd	krdd  d
  d S nB|jdkrt|j}|j	rt
| }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 )zt
    Returns the minimal polynomial of ``cos(ex)``
    see http://mathworld.wolfram.com/TrigonometryAngles.html
    r   )sqrtr@         r   r   rC   r   r   c                s    g | ]}|   |  qS r;   r;   )r<   ri   )rf   rR   rN   r;   r>   r?     s    z _minpoly_cos.<locals>.<listcomp>r]   z*%s doesn't seem to be an algebraic elementN)sympyr   r_   r   r   r   re   r   r	   r   r   r0   rp   intr&   r$   r8   r   r   rU   r   )
r   rN   r   r   r   rS   rs   r   rM   r   r;   )rf   rR   rN   r>   _minpoly_cos  s,    


$





r   c       
         sn  | j d  \}}t|j}t|j}|tt kr^|jrR|jdksR|jdkr(|dkrj d   d S |dkr~ 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}x t	|D ]}|  | 7 }qW |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@   r]   r   rC   r   r   r   r   rB   c                s   g | ]}t | qS r;   )r!   )r<   ri   )rN   r;   r>   r?     s    z _minpoly_exp.<locals>.<listcomp>z*%s doesn't seem to be an algebraic elementN)r_   r   r	   re   r   r   r   r   r   r8   r4   rU   r   )
r   rN   r   rf   re   r   rS   ri   rM   r6   r;   )rN   r>   _minpoly_exp  s8    

$r   c             C   s:   | j }|| jjd |i}t||\}}t||| }|S )zA
    Returns the minimal polynomial of a ``CRootOf`` object.
    r   )rX   rp   polyrw   r   rU   )r   rN   re   r   rM   rt   r;   r;   r>   _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|drt| |jkrt||  S |jrt	| r| |8 } xt
| }|| kr| S |} qW | jrt||f| j }nr| jrt| j}t| dd }|d r|tkrtdd	 |d
 |d  D  }|d }	dd	 |	D }
tt|
d  fdd	|	D }t| }t||}|j|   |j }|td  }tt||||||d}nt||f| j }n| jrt| j| j||}nl| jt krt!| |}nT| jt"krt#| |}n<| jtkrt$| |}n$| jt%kr*t&| |}nt'd|  |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

    rC   r@   )rx   rA   c             S   s   | d j o| d j S )Nr   r@   )is_Rational)Zitxr;   r;   r>   r[   &  s    z"_minpoly_compose.<locals>.<lambda>Tc             S   s   g | ]\}}|| qS r;   r;   )r<   Zbxr   r;   r;   r>   r?   (  s    z$_minpoly_compose.<locals>.<listcomp>FNc             S   s   g | ]\}}|j qS r;   )r   )r<   r   r^   r;   r;   r>   r?   *  s    c                s$   g | ]\}}||j   |j  qS r;   )re   r   )r<   baser^   )lcmdensr;   r>   r?   ,  s    )r   r   z*%s doesn't seem to be an algebraic element)(r   r   re   r   r   rF   rG   rA   is_QQr2   rm   is_Addr   r_   r`   r/   rM   r.   itemsr%   r   r7   r   minimal_polynomialr   r   r   rV   r   r   r   	__class__r   r   r   r   r   r    r   r   )r   rN   rP   r   rM   r~   r   r=   rs   Zr1ZdensZnumsr   r   r   r;   )r   r>   rz      sV     

rz   TFc             C   sb  ddl m} ddlm} ddlm} t| } | jr>t| dd} x|| D ]}|j	rHd}P qHW |dk	rtt|t
 }}	ntd	t }}	|s| jr|tt| j}nt}t|d
r||jkrtd||f |r(t| ||}
|
 d }
|
|||
| }|jr
t|
 }
|r|	|
|ddS |
|S |js8tdt| ||	}
|rX|	|
|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

    r   )r   )FractionField)preorder_traversalT)	recursiveFNrN   rA   z5the variable %s is an element of the ground domain %sr@   )fieldz!groebner method only works for QQ)sympy.polys.polytoolsr   sympy.polys.domainsr   Zsympy.core.basicr   r	   Z	is_numberr0   is_AlgebraicNumberr   r
   r   Zfree_symbolsr%   listrG   rA   r   rz   rr   rq   Zis_negativer   Zcollectr   rL   _minpoly_groebner)r   rN   r{   polysrx   r   r   r   rX   clsrt   r   r;   r;   r>   r   G  s>    6
r   c                s  ddl m} ddlm} tdtdi i g   }dfdd	 fd	d
 dd }d}|| } | jr~| j|S | j	r| j
| | j }n|| }|r| d } d}	| jrd| j jrd| j }
t| j|
|}	nt| rt| tj|}	|	dk	 r|	}|	dkr^ | }|| gt  }t|t |g dd}t|d \}}t||| }|rt||}||||| dk rt| }|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   )expand_multinomialrf   )r   Nc                s<   t  }|| < |d k	r*|| | | < n||| < |S )N)nextrI   )r   r   r   rf   )	generatormappingrA   r;   r>   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	r| j
jr| j
dk r| jjr| j \}}t|dd\}}| j| }t|j| | }||j| }| j
d	kr |S || j
  } | j
js<| j| j
j  td| j
j }}n| j| j
 }} |}|| }	|	krv|	d| | S |	 S n,| jr| jkr| j| jS | j S td
|  d S )NrC   r@   c                s   g | ]} |qS r;   r;   )r<   rj   )bottom_up_scanr;   r>   r?     s    z=_minpoly_groebner.<locals>.bottom_up_scan.<locals>.<listcomp>c                s   g | ]} |qS r;   r;   )r<   rj   )r   r;   r>   r?     s    r   T)r   r]   z)%s doesn't seem to be an algebraic number)rb   r   ZImaginaryUnitr   r   r   r_   r`   r   rV   r   r   Zas_coeff_addprimitive_elementr   genrI   rp   expandro   re   r   r   r   rootminpolyr   )
r   rq   r   Zeltr   algZinverser   r   rX   )r   r   rA   r   r;   r>   r     sF    




$


z)_minpoly_groebner.<locals>.bottom_up_scanc             S   sx   | j r(d| j jr(| jdk r(| jjr(dS | jrtd}g }x4| jD ]*}|jrLdS |j r>|jjr>|jdkr>dS q>W |rtd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   rc   r   r   r`   r_   )r   Zhitrf   re   r;   r;   r>   simpler_inverse  s     z*_minpoly_groebner.<locals>.simpler_inverseFr]   r@   lex)order)N)r   r   sympy.core.functionr   r*   r
   r   r   rI   r   r   re   rV   r   ro   ru   r   r2   r   ra   r   valuesr   r   rU   r   rq   r   )r   rN   r   r   r   replacer   invertedrt   r   rR   Zbusrh   Gr   rM   r;   )r   r   r   rA   r   r>   r     sF    1




r   r   c             c   s>   x8t ddddddg| ddD ]}|d	 d	krt|V  qW d
S )z1Generate coefficients for `primitive_element()`. r@   r]   rC   r   T)Z
repetitionr   N)r+   r   )rR   coeffsr;   r;   r>   _coeffs_generator6  s     r   c          
   K   sz  | st d|dk	r$t|t }}ntdt }}|dds| d dg }}t|trf|j	|}nt
||dd	}xT| dd D ]D}t||d
\}}	t|	||}| \}
}}||
| 7 }||
 qW |dds| |fS |||fS tdtd}g g  }}x^| D ]V}t|}|jr@|jr2||}nt d| n
t||}|| || q
W |dt}x|t|D ]}|tdd t||D  }t||g ||g ddd}|dd ||d |dd }}xZtt||D ]F\}\}}yt|| |dd ||< W n tk
r,   P Y nX qW P q~W td| \}}|ddsl| ||fS |||fS dS )z4Construct a common number field for all extensions. z3can't compute primitive element for empty extensionNrN   r   Fr   r@   T)r   )	extensionr   r^   )r   z#expected minimal polynomial, got %sr   c             S   s   g | ]\}}|| qS r;   r;   )r<   r   r^   r;   r;   r>   r?   s  s    z%primitive_element.<locals>.<listcomp>r   )r   r   r]   r%   )rx   z%run out of coefficient configurations)
ValueErrorr	   r   r
   r   getrD   r   r   r   r   r   rU   r   rK   rI   r*   r   Zis_PolyZis_univariater   rF   sumzipr   	enumerateZ
all_coeffsr   RuntimeErrorZclear_denoms)r   rN   r_   r   r   r   rj   extr   rM   rS   r   rh   Yr^   r=   Zcoeffs_generatorr   Hri   hr;   r;   r>   r   ?  s^    




 
r   c             C   s   | j  }|j  }|| dkr$dS ||kr0dS | j  }|j  }d|| |d   }}}x>t| }	|	| }
|
|krxP ||	 d r||
 sdS |d7 }q^W dS )z5Returns `True` if there is a chance for isomorphism. r   FTr@   rC   )r   r   Zdiscriminantr3   )rf   brR   mZdaZdbri   kZhalfre   Pr;   r;   r>   is_isomorphism_possible  s$    



r   c                s  | j jr|j jstd| j}|j|j}d|j d  }}}xtddD ]p}| j |}|j | d g fddtd|D  |g }	t	j
| }
t	_
t|	td	d
d|
t	_
dkrP |kr҈}nP fdddd D xd s  qW ttt|jdd}|||jrtd d }}x*tD ]\}}|| ||   7 }qRW || dk rdd D S S qP|| |jrdd D S |d9 }qPW dS )z2Construct field isomorphism using PSLQ algorithm. z)PSLQ doesn't support complex coefficientsd   Nr@   r:   c                s   g | ]} | qS r;   r;   )r<   ri   )Br;   r>   r?     s    z*field_isomorphism_pslq.<locals>.<listcomp>rC   g    _Bi  )ZmaxcoeffZmaxstepsc                s   g | ]}t | d   qS )r]   )r   )r<   r   )r   r;   r>   r?     s    r]   r%   )rx   r   c             S   s   g | ]
}| qS r;   r;   )r<   r   r;   r;   r>   r?     s    c             S   s   g | ]
}| qS r;   r;   )r<   r   r;   r;   r>   r?     s    )r   is_realrL   r   r   r   r   r8   rJ   r6   dpsr5   r   popr   reversedr   r{   ZremZis_zerorF   r   )rf   r   r=   rj   rR   r   prevri   AZbasisr   r   r   Zapproxrq   r;   )r   r   r>   field_isomorphism_pslq  sB    &r   c             C   s   t | j|d\}}x|D ]\}}| dkr|j  }t|d g  }}x,t|D ] \}}	||	|j	||    qVW t
| }
| j	|
 jdddkr|S | j	|
 jdddkrdd |D S qW dS dS )	z/Construct field isomorphism via factorization. )r   r@   T)Zchopr   c             S   s   g | ]
}| qS r;   r;   )r<   r   r;   r;   r>   r?     s    z,field_isomorphism_factor.<locals>.<listcomp>N)r   r   r   ZrepZTCZto_sympy_listrF   r   rK   r   r   rJ   )rf   r   r   rM   r=   r   r   r   ri   rq   r   r;   r;   r>   field_isomorphism_factor  s    r   c             K   s   t | t | } }| js t| } |js.t|}| |kr>|  S | j }|j }|dkrb| jgS || dkrrdS |ddryt| |}|dk	r|S W n t	k
r   Y nX t
| |S )z4Construct an isomorphism between two number fields. r@   r   NfastT)r	   r   r   r   r   r   r   r   r   rL   r   )rf   r   r_   rR   r   rt   r;   r;   r>   field_isomorphism  s*    


r   c             K   s   | d}t| drt| } n| g} t| dkrLt| d tkrLt| d S t| |dd\}}tdd t	|| D }|d	krt||fS t
|}|jst||d
}t||}|d	k	rt||S td||jf d	S )z7Express `extension` in the field generated by `theta`. r   __iter__r@   r   T)r   c             S   s   g | ]\}}|| qS r;   r;   )r<   rq   r   r;   r;   r>   r?   (  s    z#to_number_field.<locals>.<listcomp>N)r   z%s is not in a subfield of %s)r   rG   r   rF   typerE   r   r   r   r   r	   r   r   r   r   )r   Zthetar_   r   r   r   r   r;   r;   r>   to_number_field  s$    




r   c                   s8   e Zd ZdZ fddZ fddZ fddZ  ZS )IntervalPrinterz?Use ``lambda`` printer but print numbers as ``mpi`` intervals. c                s   dt t| | S )Nz	mpi('%s'))superr   _print_Integer)selfrX   )r   r;   r>   r   >  s    zIntervalPrinter._print_Integerc                s   dt t| | S )Nz	mpi('%s'))r   r   _print_Rational)r   rX   )r   r;   r>   r   A  s    zIntervalPrinter._print_Rationalc                s   t t| j|ddS )NT)Zrational)r   r   
_print_Pow)r   rX   )r   r;   r>   r   D  s    zIntervalPrinter._print_Pow)__name__
__module____qualname____doc__r   r   r   __classcell__r;   r;   )r   r>   r   ;  s   r   c       
      C   s   t | } | jr| | fS | js$tdtd| dt d}t| dd}|jdd}tj	d }}zNxH|s| } x8|D ]"\}}	|| j
krn| j|	krnd}P qnW t j	d	9  _	q^W W d
|t_	X |d
k	r|j||	||d\}}	||	fS )z<Give a rational isolating interval for an algebraic number. z+complex algebraic numbers are not supportedr;   mpmath)modulesZprinterT)r   )ZsqfFrC   N)rT   r   )r	   r   r   rL   r,   r   r   	intervalsr6   r   rf   r   Zrefine_root)
r   rT   r   funcr   r   r   Zdonerf   r   r;   r;   r>   isolateH  s,    r   )NN)N)NTFN)N)N)NF)kr   Z
__future__r   r   r   r   r   r   r   r   r	   r
   r   r   r   Z&sympy.functions.elementary.exponentialr   Z(sympy.functions.elementary.trigonometricr   r   r   r   r   r   r   r   r   r   r   r   r   r   Zsympy.polys.polyerrorsr   r   r   r   Zsympy.polys.rootoftoolsr    Zsympy.polys.specialpolysr!   Zsympy.polys.polyutilsr"   r#   r   r$   r%   Zsympy.polys.orthopolysr&   Zsympy.polys.ringsr'   Zsympy.polys.ring_seriesr(   Zsympy.printing.lambdareprr)   Zsympy.utilitiesr*   r+   r,   r-   r.   Zsympy.core.exprtoolsr/   r   r0   Zsympy.simplify.radsimpr1   rn   r2   Zsympy.ntheoryr3   Zsympy.ntheory.factor_r4   r   r5   r6   Zsympy.core.compatibilityr7   r8   rU   rm   ru   r   r   r|   r   r   r   r   r   r   r   rz   r   r   r   __all__rK   r   r   r   r   r   r   r   r   r   r;   r;   r;   r>   <module>   sp   04&A9
N
5& %G_ 
	K6# 