B
    [9                 @   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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mZmZ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-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZC ddlDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZRmSZS ddlTmUZUmVZVmWZW ddlXmYZYmZZZm[Z[m\Z\m]Z] dd	l^m_Z_ dd
l`maZa ddlbmcZcmdZdmeZemfZf ddlgmhZhmiZimjZj ddlkmlZl ddlmmnZompZq ddlrmsZs dd Ztdd Zudd Zvdd Zwdd Zxdd Zydd Zzdd Z{d d! Z|dTd#d$Z}d%d& Z~d'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9d: ZdUd<d=Zd>d? Zd@dA ZdBdC ZdDdE ZdFdG ZdHdI ZdJdK ZdLdM ZdNdO ZdPdQ ZdRdS Zd;S )Vz:Polynomial factorization routines in characteristic zero.     )print_functiondivision)gf_from_int_polygf_to_int_poly	gf_lshift
gf_add_mulgf_mulgf_divgf_remgf_gcdexgf_sqf_pgf_factor_sqf	gf_factor)dup_LCdmp_LCdmp_ground_LCdup_TCdup_convertdmp_convert
dup_degree
dmp_degreedmp_degree_indmp_degree_listdmp_from_dict
dmp_zero_pdmp_onedmp_nest	dmp_raise	dup_strip
dmp_grounddup_inflatedmp_excludedmp_include
dmp_inject	dmp_ejectdup_terms_gcddmp_terms_gcd)dup_negdmp_negdup_adddmp_adddup_subdmp_subdup_muldmp_muldup_sqrdmp_powdup_divdmp_divdup_quodmp_quo
dmp_expanddmp_add_muldup_sub_muldmp_sub_mul
dup_lshiftdup_max_normdmp_max_normdup_l1_normdup_mul_grounddmp_mul_grounddup_quo_grounddmp_quo_ground)dup_clear_denomsdmp_clear_denoms	dup_truncdmp_ground_truncdup_content	dup_monicdmp_ground_monicdup_primitivedmp_ground_primitivedmp_eval_taildmp_eval_indmp_diff_eval_indmp_compose	dup_shift
dup_mirror)dmp_primitivedup_inner_gcddmp_inner_gcd)	dup_sqf_pdup_sqf_normdmp_sqf_normdup_sqf_partdmp_sqf_part)_sort_factors)query)ExtraneousFactorsDomainErrorCoercionFailedEvaluationFailed)	nextprimeisprime	factorint)subsets)ceillog)rangec             C   sX   g }xJ|D ]B}d}x*t | ||\}}|s8||d  } }qP qW |||f q
W t|S )z:Determine multiplicities of factors using trial division. r      )r1   appendrX   )ffactorsKresultfactorkqr ro   6lib/python3.7/site-packages/sympy/polys/factortools.pydup_trial_divisionR   s    
rq   c       	      C   s`   g }xR|D ]J}d}x2t | |||\}}t||r@||d  } }qP qW |||f q
W t|S )z:Determine multiplicities of factors using trial division. r   re   )r2   r   rf   rX   )	rg   rh   uri   rj   rk   rl   rm   rn   ro   ro   rp   dmp_trial_divisionf   s    

rs   c             C   sB   t | |}tt| |}t| }|||d d|  | | S )z5Mignotte bound for univariate polynomials in `K[x]`. re      )r:   absr   r   sqrt)rg   ri   abnro   ro   rp   dup_zz_mignotte_boundz   s    
rz   c             C   sL   t | ||}tt| ||}tt| |}|||d d|  | | S )z7Mignotte bound for multivariate polynomials in `K[X]`. re   rt   )r;   ru   r   sumr   rv   )rg   rr   ri   rw   rx   ry   ro   ro   rp   dmp_zz_mignotte_bound   s    r|   c             C   sJ  | d }t ||||}t|||}tt|||||\}	}
t|	||}	t|
||}
tt|||t|	|||}tt|||||}tt||
|||}tt|||t||||}tt||jg|||}tt|||||\}}t|||}t|||}tt|||t||||}tt|||||}tt|||||}||||fS )a  
    One step in Hensel lifting in `Z[x]`.

    Given positive integer `m` and `Z[x]` polynomials `f`, `g`, `h`, `s`
    and `t` such that::

        f == g*h (mod m)
        s*g + t*h == 1 (mod m)

        lc(f) is not a zero divisor (mod m)
        lc(h) == 1

        deg(f) == deg(g) + deg(h)
        deg(s) < deg(h)
        deg(t) < deg(g)

    returns polynomials `G`, `H`, `S` and `T`, such that::

        f == G*H (mod m**2)
        S*G + T**H == 1 (mod m**2)

    References
    ==========

    1. [Gathen99]_

    rt   )r7   rC   r1   r-   r)   r+   one)mrg   ghstri   Merm   rn   rr   GHrx   cdSTro   ro   rp   dup_zz_hensel_step   s$    r   c          	   C   s  t |}t||}|dkrHt|||| | d |}t|| | |gS | }|d }	ttt|d}
t|g| }x(|d|	 D ]}t	|t|| | |}qW t||	 | }x,||	d d D ]}t	|t|| | |}qW t
||| |\}}}t|| }t|| }t|| }t|| }x>td|
d D ],}t||||||||d  \}}}}}q$W t| ||d|	 ||t| |||	d || S )a  
    Multifactor Hensel lifting in `Z[x]`.

    Given a prime `p`, polynomial `f` over `Z[x]` such that `lc(f)`
    is a unit modulo `p`, monic pair-wise coprime polynomials `f_i`
    over `Z[x]` satisfying::

        f = lc(f) f_1 ... f_r (mod p)

    and a positive integer `l`, returns a list of monic polynomials
    `F_1`, `F_2`, ..., `F_r` satisfying::

       f = lc(f) F_1 ... F_r (mod p**l)

       F_i = f_i (mod p), i = 1..r

    References
    ==========

    1. [Gathen99]_

    re   r   rt   N)lenr   r=   ZgcdexrC   int_ceil_logr   r   r   r   rd   r   dup_zz_hensel_lift)prg   Zf_listlri   rn   lcFr~   rl   r   r   Zf_ir   r   r   _ro   ro   rp   r      s.    




,r   c             C   s(   ||d kr|| }|sdS | | dkS )Nrt   Tr   ro   )fcrm   plro   ro   rp   _test_pl   s
    r   c                s  t | }|dkr| gS | d }t| |}t| |}tt|||d d|  | | }t|d d|  |d| d   }ttdt|d }td| t| }	g }
xtd|	d D ]v}t	|r|| dkrq|
|}t| |}t|||sqt|||d }|
||f t|dk s2t|
dkrP qW t|
dd	 d
\}tttd| d }fdd|D }t| |||}tt|}t|}g d }}| }xd| t|kr|xt||D ] |dkr"d}x D ]}||| d  }qW || }t|||sqn`|g}x D ]}t||| |}q.W t|||}t||d }|d }|r|| dkrq|g}t  |  }|dkr|g}x D ]}t||| |}qW t|||}x|D ]}t||| |}qW t|||}t||}t||}|| |kr|} fdd|D }t||d }t||d } || t| |}P qW |d7 }qW || g S )z4Factor primitive square-free polynomials in `Z[x]`. re   rt      r         c             S   s   t | d S )Nre   )r   )xro   ro   rp   <lambda>%  s    z#dup_zz_zassenhaus.<locals>.<lambda>)keyc                s   g | ]}t | qS ro   )r   ).0Zff)r   ro   rp   
<listcomp>)  s    z%dup_zz_zassenhaus.<locals>.<listcomp>c                s   g | ]}| kr|qS ro   ro   )r   i)r   ro   rp   r   ]  s    )r   r:   r   r   ru   rv   r   r   rd   r_   convertr   r   r   rf   r   minr   setra   r   r-   rC   rH   r<   )rg   ri   ry   r   Arx   BCZgammaZboundrw   Zpxr   ZfsqfxZfsqfr   Zmodularr   Zsorted_Tr   rh   r   r   rm   r   r   r   ZT_SZG_normZH_normro   )r   r   rp   dup_zz_zassenhaus  s    

*$












r   c             C   sd   t | |}t| |}t| dd |}|r`tt|}x(| D ]}|| r@||d  r@dS q@W dS )z2Test irreducibility using Eisenstein's criterion. re   Nrt   T)r   r   rE   r`   r   keys)rg   ri   r   tcZe_fcZe_ffr   ro   ro   rp   dup_zz_irreducible_pl  s    

r   Fc             C   s  |j r<y||  }}t| ||} W qF tk
r8   dS X n
|jsFdS t| |}t| |}|dksr|dkrv|dkrvdS |st| |\}}||jks|| dfgkrdS t	| }g g  }	}
x$t
|ddD ]}|	d| |  qW x(t
|d ddD ]}|
d| |  qW tt|	|}	tt|
|}
t|	t|
d||}|t||rRt||}|| kr`dS t| |}	|t|	|rt|	|}	||	krt|	|rdS t||}t|||krt||rdS dS )ah  
    Efficiently test if ``f`` is a cyclotomic polnomial.

    Examples
    ========

    >>> from sympy.polys import ring, ZZ
    >>> R, x = ring("x", ZZ)

    >>> f = x**16 + x**14 - x**10 + x**8 - x**6 + x**2 + 1
    >>> R.dup_cyclotomic_p(f)
    False

    >>> g = x**16 + x**14 - x**10 - x**8 - x**6 + x**2 + 1
    >>> R.dup_cyclotomic_p(g)
    True

    Fre   r   r   T)Zis_QQget_ringr   r\   is_ZZr   r   dup_factor_listr}   r   rd   insertr/   r   r+   r9   is_negativer'   rO   dup_cyclotomic_prV   )rg   ri   ZirreducibleK0r   r   coeffrh   ry   r   r   r   r   r   ro   ro   rp   r   {  sL    







r   c             C   sT   |j |j  g}x@t|  D ]0\}}tt|||||}t|||d  |}qW |S )z0Efficiently generate n-th cyclotomic polnomial. re   )r}   r`   itemsr3   r    )ry   ri   r   r   rl   ro   ro   rp   dup_zz_cyclotomic_poly  s
    r   c                s~    j  j  gg}xht|  D ]X\} fdd|D }|| x0td|D ]"} fdd|D }|| qPW qW |S )Nc                s    g | ]}t t| | qS ro   )r3   r    )r   r   )ri   r   ro   rp   r     s    z-_dup_cyclotomic_decompose.<locals>.<listcomp>re   c                s   g | ]}t | qS ro   )r    )r   rm   )ri   r   ro   rp   r     s    )r}   r`   r   extendrd   )ry   ri   r   rl   Qr   ro   )ri   r   rp   _dup_cyclotomic_decompose  s    
r   c             C   s   t | |t| | }}t| dkr&dS |dks6|dkr:dS tdd | dd D rXdS t| }t||}||sx|S g }x(td| |D ]}||kr|| qW |S dS )	a  
    Efficiently factor polynomials `x**n - 1` and `x**n + 1` in `Z[x]`.

    Given a univariate polynomial `f` in `Z[x]` returns a list of factors
    of `f`, provided that `f` is in the form `x**n - 1` or `x**n + 1` for
    `n >= 1`. Otherwise returns None.

    Factorization is performed using using cyclotomic decomposition of `f`,
    which makes this method much faster that any other direct factorization
    approach (e.g. Zassenhaus's).

    References
    ==========

    1. [Weisstein09]_

    r   Nre   )r   re   c             s   s   | ]}t |V  qd S )N)bool)r   Zcfro   ro   rp   	<genexpr>  s    z+dup_zz_cyclotomic_factor.<locals>.<genexpr>r   rt   )r   r   r   anyr   is_onerf   )rg   ri   Zlc_fZtc_fry   r   r   r   ro   ro   rp   dup_zz_cyclotomic_factor  s     

r   c             C   s   t | |\}}t|}t||dk r6| t|| }}|dkrF|g fS |dkrX||gfS tdrtt||rt||gfS d}tdrt||}|dkrt||}|t|ddfS )z9Factor square-free (non-primitive) polyomials in `Z[x]`. r   re   USE_IRREDUCIBLE_IN_FACTORNUSE_CYCLOTOMIC_FACTORF)Zmultiple)	rH   r   r   r'   rY   r   r   r   rX   )rg   ri   contr   ry   rh   ro   ro   rp   dup_zz_factor_sqf  s"    




r   c             C   s   t | |\}}t|}t||dk r6| t|| }}|dkrF|g fS |dkr\||dfgfS tdr|t||r|||dfgfS t||}d}tdrt||}|dkrt||}t	| ||}||fS )a  
    Factor (non square-free) polynomials in `Z[x]`.

    Given a univariate polynomial `f` in `Z[x]` computes its complete
    factorization `f_1, ..., f_n` into irreducibles over integers::

                f = content(f) f_1**k_1 ... f_n**k_n

    The factorization is computed by reducing the input polynomial
    into a primitive square-free polynomial and factoring it using
    Zassenhaus algorithm. Trial division is used to recover the
    multiplicities of factors.

    The result is returned as a tuple consisting of::

              (content(f), [(f_1, k_1), ..., (f_n, k_n))

    Consider polynomial `f = 2*x**4 - 2`::

        >>> from sympy.polys import ring, ZZ
        >>> R, x = ring("x", ZZ)

        >>> R.dup_zz_factor(2*x**4 - 2)
        (2, [(x - 1, 1), (x + 1, 1), (x**2 + 1, 1)])

    In result we got the following factorization::

                 f = 2 (x - 1) (x + 1) (x**2 + 1)

    Note that this is a complete factorization over integers,
    however over Gaussian integers we can factor the last term.

    By default, polynomials `x**n - 1` and `x**n + 1` are factored
    using cyclotomic decomposition to speedup computations. To
    disable this behaviour set cyclotomic=False.

    References
    ==========

    1. [Gathen99]_

    r   re   r   Nr   )
rH   r   r   r'   rY   r   rV   r   r   rq   )rg   ri   r   r   ry   r   rh   ro   ro   rp   dup_zz_factor)  s&    +



r   c             C   sx   || g}x`| D ]X}t |}x@t|D ]4}x |dkrJ|||}|| }q,W ||r&dS q&W || qW |dd S )z,Wang/EEZ: Compute a set of valid divisors.  re   N)ru   reversedgcdr   rf   )Ecsctri   rj   rm   rn   ro   ro   rp   dmp_zz_wang_non_divisorsq  s    



r   c                s   t t|  |d s tdt |  |}t|s@tdt|\}}t|rp| t| }}|d  fdd|D }	t|	||}
|
dk	r|||	fS tddS )z2Wang/EEZ: Test evaluation points for suitability. re   zno luckc                s   g | ]\}}t | qS ro   )rJ   )r   r   r   )r   ri   vro   rp   r     s    z+dmp_zz_wang_test_points.<locals>.<listcomp>N)	rJ   r   r]   rS   rH   r   r   r'   r   )rg   r   r   r   rr   ri   r   r   r   r   Dro   )r   ri   r   rp   dmp_zz_wang_test_points  s    

r   c          	   C   s  g dgt | |d   }}	}
x|D ]}t|
|}t||| }x~ttt |D ]j}d|| ||   }}\}}x|| s|| |d  }}qtW |dkrRt|t|||
||
|d }|	|< qRW || q$W tdd |	D rt	g g  }}xt
||D ]\}}t|||
|}t||}||r0|| }n4|||}|| ||  }}t|||||  }}t|||
|}|| ||  qW ||r| ||fS g g  }}x@t
||D ]2\}}|t|||
| |t||d| qW t| |t |d  ||} | ||fS )z0Wang/EEZ: Compute correct leading coefficients. r   re   c             s   s   | ]}| V  qd S )Nro   )r   jro   ro   rp   r     s    z*dmp_zz_wang_lead_coeffs.<locals>.<genexpr>)r   r   r   r   rd   r.   r0   rf   r   rZ   ziprJ   r   r   r=   r>   )rg   r   r   r   r   r   rr   ri   r   Jr   r   r   r   r   rl   r   r   r   ZCCZHHr   Zccr   ZCCCZHHHro   ro   rp   dmp_zz_wang_lead_coeffs  sB    


&





r   c          	   C   s  t | dkr| \}}t||}t||}t||||\}}	}
t|||}t|	||}	t||||\}}t|	||||}	t||}t|	|}	||	g}n| d g}
x0t| dd D ]}|
dt	||
d | qW g dgg }}xJt
| |
D ]<\}}t||g|d g d|d|\}	}||	 || qW g ||d g  }}xVt
|| D ]H\}}t||}t||}tt||||||}t||}|| qLW |S )z2Wang/EEZ: Solve univariate Diophantine equations. rt   r   re   r   )r   r   r   r   r	   r   r   r   r   r-   r   dmp_zz_diophantinerf   r
   )r   r~   r   ri   rw   rx   rg   r   r   r   r   rm   rj   r   r   rn   ro   ro   rp   dup_zz_diophantine  s8    




 



r   c          	      s  |sdd | D }t |}xpt|D ]d\}	}
|
s2q$t| ||	  }xBtt||D ]0\}\}}t||
 }tt||  ||< qTW q$W nBt|}t|  }|d |dd  }}g g  }}x6| D ].}|	t
||  |	t|||  qW t||| }d t|||| } fdd|D }x(t||D ]\}}t||| }qHW t| }t j| g| }t| }x& td|D ]}t|rP t|| }t||d || }t|st| |d  }t|||| }x2t|D ]&\}	}tt|d | ||	< q W x2tt||D ] \}	\}}t|| ||	< qZW x(t||D ]\}}t||| }qW t| }qW  fdd|D }|S )	z4Wang/EEZ: Solve multivariate Diophantine equations. c             S   s   g | ]}g qS ro   ro   )r   r   ro   ro   rp   r     s    z&dmp_zz_diophantine.<locals>.<listcomp>r   Nre   c                s   g | ]}t |d  qS )re   )r   )r   r   )ri   r   ro   rp   r   $  s    r   c                s   g | ]}t | qS ro   )rD   )r   r   )ri   r   rr   ro   rp   r   D  s    )r   	enumerater   r   r=   rC   r)   r   r5   rf   r4   rK   r   r8   rD   r   r}   r   maprd   r   r.   rL   r@   	factorialr   r*   )r   r   r   r   r   rr   ri   r   ry   r   r   r   r   r   r   r   rw   r   r   rg   r   rx   r~   r   rl   ro   )ri   r   rr   r   rp   r     sV    $


"r   c          
   C   s  | gt ||d   }}}	t|}xVtt|dd D ]>\}
}t|d |||
 ||
 |}|dt|||	|
 | q8W tt| |dd }xt	t
d|d ||D ]\}}}t||d  }}|d|d  ||d d  }}x^tt	||D ]L\}
\}}tt|||	|||d |}|gt|dd d|d | ||
< qW t|j| g||}t||}t|t|||||}t|||}x|t
d|D ]}t||rP t||||}t||d ||||}t||d st|||d |d |}t||||||d |}xPtt	||D ]>\}
\}}t|t|d|d ||||}t||||||
< q(W t|t|||||}t||||}qW qW t|||| krtn|S dS )z-Wang/EEZ: Parallel Hensel lifting algorithm. re   Nr   rt   )r   listr   r   rK   r   rD   maxr   r   rd   rJ   r   r   r}   r   r,   r5   r   r   r   r.   rL   r@   r   r   r6   rZ   )rg   r   LCr   r   rr   ri   r   ry   r   r   rw   r   r   r   r   wIr   r   r   r~   r   r   Zdjrl   r   r   r   ro   ro   rp   dmp_zz_wang_hensel_liftingI  s@    &"(
r   Nc           	      s\  ddl m} ||tt|  |d  \}}t| | } t|}	dkr`|dkr\dndtg g  jg| df\}
}}}yPt| |||| \}}}t	| \}}t
|}|dkr| gS |||||fg}W n tk
r   Y nX td}td}td}x$t
||k r$xt|D ]} fd	d
t|D }t||
kr|
t| nqyt| |||| \}}}W n tk
r   wY nX t	| \}}t
|}|dk	r||kr||k rg | }}nqn|}|dkr| gS ||||||f t
||krP qW |7 qW d\}}}xL|D ]D\}}}}}t| }|dk	rl||k rp|}|}n|}|d7 }q6W || \}}}}}| }y4t| |||||| \} }}t| ||||	| }W n: tk
r   tdrt|| d S tdY nX dg  }}xH|D ]@} t| | \}}  t| | rHt| | } ||  qW |S )aV  
    Factor primitive square-free polynomials in `Z[X]`.

    Given a multivariate polynomial `f` in `Z[x_1,...,x_n]`, which is
    primitive and square-free in `x_1`, computes factorization of `f` into
    irreducibles over integers.

    The procedure is based on Wang's Enhanced Extended Zassenhaus
    algorithm. The algorithm works by viewing `f` as a univariate polynomial
    in `Z[x_2,...,x_n][x_1]`, for which an evaluation mapping is computed::

                      x_2 -> a_2, ..., x_n -> a_n

    where `a_i`, for `i = 2, ..., n`, are carefully chosen integers.  The
    mapping is used to transform `f` into a univariate polynomial in `Z[x_1]`,
    which can be factored efficiently using Zassenhaus algorithm. The last
    step is to lift univariate factors to obtain true multivariate
    factors. For this purpose a parallel Hensel lifting procedure is used.

    The parameter ``seed`` is passed to _randint and can be used to seed randint
    (when an integer) or (for testing purposes) can be a sequence of numbers.

    References
    ==========

    1. [Wang78]_
    2. [Geddes92]_

    r   )_randintre   Nrt   ZEEZ_NUMBER_OF_CONFIGSZEEZ_NUMBER_OF_TRIESZEEZ_MODULUS_STEPc                s   g | ]}  qS ro   ro   )r   r   )ri   modrandintro   rp   r     s    zdmp_zz_wang.<locals>.<listcomp>)Nr   r   ZEEZ_RESTART_IF_NEEDEDz3we need to restart algorithm with better parameters)Zsympy.utilities.randtestr   dmp_zz_factorr   r|   r^   r   zeror   r   r   r]   rY   rd   tupleaddrf   r:   r   r   rZ   dmp_zz_wangrI   r   r   r(   ) rg   rr   ri   r   Zseedr   r   r   rx   r   historyZconfigsr   rn   r   r   r   r   r   Zeez_num_configsZeez_num_triesZeez_mod_stepZrrZs_normZs_argr   Z_s_normZorig_fr   rh   negativerj   ro   )ri   r   r   rp   r   }  s     











r   c       	      C   s   |st | |S t| |r"|jg fS t| ||\}}t|||dk rV| t||| }}tdd t||D rv|g fS t|||\}}g }t	||dkrt
|||}t|||}t| |||}x2t||d |d D ]\}}|d|g|f qW |t|fS )a  
    Factor (non square-free) polynomials in `Z[X]`.

    Given a multivariate polynomial `f` in `Z[x]` computes its complete
    factorization `f_1, ..., f_n` into irreducibles over integers::

                 f = content(f) f_1**k_1 ... f_n**k_n

    The factorization is computed by reducing the input polynomial
    into a primitive square-free polynomial and factoring it using
    Enhanced Extended Zassenhaus (EEZ) algorithm. Trial division
    is used to recover the multiplicities of factors.

    The result is returned as a tuple consisting of::

             (content(f), [(f_1, k_1), ..., (f_n, k_n))

    Consider polynomial `f = 2*(x**2 - y**2)`::

        >>> from sympy.polys import ring, ZZ
        >>> R, x,y = ring("x,y", ZZ)

        >>> R.dmp_zz_factor(2*x**2 - 2*y**2)
        (2, [(x - y, 1), (x + y, 1)])

    In result we got the following factorization::

                    f = 2 (x - y) (x + y)

    References
    ==========

    1. [Gathen99]_

    r   c             s   s   | ]}|d kV  qdS )r   Nro   )r   r   ro   ro   rp   r   :  s    z dmp_zz_factor.<locals>.<genexpr>re   )r   r   r   rI   r   r(   allr   rP   r   rW   r   rs   r   r   rX   )	rg   rr   ri   r   r   r   rh   r   rl   ro   ro   rp   r     s$    $


r   c             C   s   t | t| | }}t| |} |dkr.|g fS |dkrD|| dfgfS t| ||  } }t| |\}}}t||j}t|dkr|| |t |  fgfS ||j }	xLt	|D ]@\}
\}}t
||j|}t|||\}}}t||	|}|||
< qW t|||}||fS )z<Factor univariate polynomials over algebraic number fields. r   re   )r   r   rF   rV   rT   dup_factor_list_includedomr   unitr   r   rQ   rN   rq   )rg   ri   ry   r   r   r   r   rn   rh   r   r   rk   r   r   ro   ro   rp   dup_ext_factorL  s&    

r   c             C   s  |st | |S t| ||}t| ||} tdd t| |D rF|g fS t| |||  } }t| ||\}}}t|||j}t	|dkr|| g }	}nnt
|j||j g|d|}
xRt|D ]F\}\}}t|||j|}t||||\}}}t||
||}|||< qW |t||||fS )z>Factor multivariate polynomials over algebraic number fields. c             s   s   | ]}|d kV  qdS )r   Nro   )r   r   ro   ro   rp   r   s  s    z!dmp_ext_factor.<locals>.<genexpr>re   r   )r   r   rG   r   r   rW   rU   dmp_factor_list_includer   r   r   r}   r   r   r   rR   rM   rs   )rg   rr   ri   r   r   r   r   rn   rh   r   r   r   rk   r   r   ro   ro   rp   dmp_ext_factork  s$    
r   c             C   sd   t | ||j} t| |j|j\}}x.t|D ]"\}\} }t | |j||f||< q,W |||j|fS )z2Factor univariate polynomials over finite fields. )r   r   r   r   r   r   )rg   ri   r   rh   r   rl   ro   ro   rp   dup_gf_factor  s
    r   c             C   s   t ddS )z4Factor multivariate polynomials over finite fields. z+multivariate polynomials over finite fieldsN)NotImplementedError)rg   rr   ri   ro   ro   rp   dmp_gf_factor  s    r   c             C   s  t | |\}} t| |\}} |jr4t| |\}}n|jrLt| |\}}n|jsn||  }}t| ||} nd}|j	r|
 }t| ||\}} t| ||} n|}|jrt| |\}}nt|jr t| d|\} }	t| |	|j\}}x,t|D ] \}
\} }t| |	||f||
< qW |||j}ntd| |j	rx.t|D ]"\}
\} }t| |||f||
< q>W |||}|||}|rx\t|D ]P\}
\} }t| |}t| ||} t| ||} | |f||
< |||||}qW |||}|}|r|d|j|jg|f || t|fS )z0Factor polynomials into irreducibles in `K[x]`. Nr   z#factorization not supported over %s)r%   rH   is_FiniteFieldr   is_Algebraicr   is_Exact	get_exactr   is_Fieldr   rA   r   r   is_Polyr#   dmp_factor_listr   r   r$   r   r[   quor:   r?   mulpowr   r}   r   rX   )rg   r   r   r   r   rh   
K0_inexactri   denomrr   r   rl   max_normro   ro   rp   r     sR    
r   c             C   sX   t | |\}}|s"t|gdfgS t|d d ||}||d d fg|dd  S dS )z0Factor polynomials into irreducibles in `K[x]`. re   r   N)r   r   r=   )rg   ri   r   rh   r   ro   ro   rp   r     s
    r   c             C   s  |st | |S t| ||\}} t| ||\}} |jrHt| ||\}}n|jrbt| ||\}}n|js||  }}t	| |||} nd}|j
r| }t| |||\}	} t	| |||} n|}|jrt| ||\}
} }t| ||\}}xt|D ]"\}\} }t| |
|||f||< qW nv|jrt| ||\} }t| ||j\}}x.t|D ]"\}\} }t| |||f||< qNW |||j}ntd| |j
r\x0t|D ]$\}\} }t	| ||||f||< qW |||}|||	}|r\xbt|D ]V\}\} }t| ||}t| |||} t	| |||} | |f||< |||||}qW |||}|}xZtt|D ]J\}}|s|qjd||  d d|  |ji}| dt!||||f qjW || t"|fS )z0Factor polynomials into irreducibles in `K[X]`. Nz#factorization not supported over %s)r   )re   r   )#r   r&   rI   r   r   r   r   r   r   r   r   r   rB   r   r!   r   r   r"   r   r#   r   r   r$   r   r[   r   r;   r@   r   r   r   r}   r   r   rX   )rg   rr   r   r   r   r   rh   r   ri   r   Zlevelsr   r   rl   r   r   Ztermro   ro   rp   r     sb    
r   c             C   sj   |st | |S t| ||\}}|s2t||dfgS t|d d |||}||d d fg|dd  S dS )z0Factor polynomials into irreducibles in `K[X]`. re   r   N)r   r   r   r>   )rg   rr   ri   r   rh   r   ro   ro   rp   r   ,  s    
r   c             C   s   t | d|S )z:Returns ``True`` if ``f`` has no factors over its domain. r   )dmp_irreducible_p)rg   ri   ro   ro   rp   dup_irreducible_p:  s    r   c             C   s@   t | ||\}}|sdS t|dkr(dS |d \}}|dkS dS )z:Returns ``True`` if ``f`` has no factors over its domain. Tre   Fr   N)r   r   )rg   rr   ri   r   rh   rl   ro   ro   rp   r   ?  s    r   )F)NN)__doc__Z
__future__r   r   Zsympy.polys.galoistoolsr   r   r   r   r   r	   r
   r   r   r   r   Zsympy.polys.densebasicr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   Zsympy.polys.densearithr'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   Zsympy.polys.densetoolsrA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   Zsympy.polys.euclidtoolsrP   rQ   rR   Zsympy.polys.sqfreetoolsrS   rT   rU   rV   rW   Zsympy.polys.polyutilsrX   Zsympy.polys.polyconfigrY   Zsympy.polys.polyerrorsrZ   r[   r\   r]   Zsympy.ntheoryr^   r_   r`   Zsympy.utilitiesra   Zmathrb   r   rc   r   Zsympy.core.compatibilityrd   rq   rs   rz   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ro   ro   ro   rp   <module>   s`   4hpD		99g
L,H60D4
 A>I