o
    oh                     @   s@  d Z ddlmZ ddl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/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZD ddlEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZRmSZSmTZT ddlUmVZVmWZWmXZX dd	lYmZZZm[Z[m\Z\m]Z]m^Z^m_Z_m`Z` dd
lambZb ddlcmdZd ddlemfZfmgZgmhZhmiZi ddljmkZk ddllmmZnmoZpmqZr edkrddlsmtZt ndZtdd Zudd Zvdd Zwdd Zxdd Zydd Zzdd Z{d d! Z|d"d# Z}d]d%d&Z~d'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9d: Zd;d< Zd^d=d>Zd?d@ ZdAdB ZdCdD ZdEdF ZdGdH ZdIdJ ZdKdL ZdMdN ZdOdP ZdQdR ZdSdT ZdUdV ZdWdX ZdYdZ Zd[d\ ZdS )_z:Polynomial factorization routines in characteristic zero.     )GROUND_TYPES)_randint)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	dup_shift	dmp_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_dup_check_degrees_dmp_check_degrees)_sort_factors)query)ExtraneousFactorsDomainErrorCoercionFailedEvaluationFailed)subsets)ceilloglog2flint)	fmpz_polyNc                 C   sb   g }|D ](}d}	 t | ||\}}|s||d } }nnq	|dkr%td|||f qt|S )z
    Determine multiplicities of factors for a univariate polynomial
    using trial division.

    An error will be raised if any factor does not divide ``f``.
    r   T   trial division failed)r1   RuntimeErrorappendrZ   )ffactorsKresultfactorkqr rr   k/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/polys/factortools.pydup_trial_divisionX   s   rt   c           	      C   sj   g }|D ],}d}	 t | |||\}}t||r||d } }nnq	|dkr)td|||f qt|S )z
    Determine multiplicities of factors for a multivariate polynomial
    using trial division.

    An error will be raised if any factor does not divide ``f``.
    r   Trf   rg   )r2   r   rh   ri   rZ   )	rj   rk   url   rm   rn   ro   rp   rq   rr   rr   rs   dmp_trial_divisiont   s   
rv   c                 C   s   ddl m} t| }t|d }t|d }|tdd | D }||d |}||d |d }|t| |}	|| ||	  }
|
t| |7 }
t|
d d }
|
S )a  
    The Knuth-Cohen variant of Mignotte bound for
    univariate polynomials in ``K[x]``.

    Examples
    ========

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

    >>> f = x**3 + 14*x**2 + 56*x + 64
    >>> R.dup_zz_mignotte_bound(f)
    152

    By checking ``factor(f)`` we can see that max coeff is 8

    Also consider a case that ``f`` is irreducible for example
    ``f = 2*x**2 + 3*x + 4``. To avoid a bug for these cases, we return the
    bound plus the max coefficient of ``f``

    >>> f = 2*x**2 + 3*x + 4
    >>> R.dup_zz_mignotte_bound(f)
    6

    Lastly, to see the difference between the new and the old Mignotte bound
    consider the irreducible polynomial:

    >>> f = 87*x**7 + 4*x**6 + 80*x**5 + 17*x**4 + 9*x**3 + 12*x**2 + 49*x + 26
    >>> R.dup_zz_mignotte_bound(f)
    744

    The new Mignotte bound is 744 whereas the old one (SymPy 1.5.1) is 1937664.


    References
    ==========

    ..[1] [Abbott13]_

    r   )binomial   c                 s   s    | ]}|d  V  qdS )rx   Nrr   .0cfrr   rr   rs   	<genexpr>       z(dup_zz_mignotte_bound.<locals>.<genexpr>rf   )	(sympy.functions.combinatorial.factorialsrw   r   _ceilsqrtsumabsr   r:   )rj   rl   rw   ddeltadelta2	eucl_normt1t2lcboundrr   rr   rs   dup_zz_mignotte_bound   s   )r   c                 C   sL   t | ||}tt| ||}tt| |}|||d d|  | | S )z7Mignotte bound for multivariate polynomials in `K[X]`. rf   rx   )r;   r   r   r   r   r   )rj   ru   rl   abnrr   rr   rs   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]_

    rx   )r7   rC   r1   r-   r)   r+   one)mrj   ghstrl   Merp   rq   ru   GHr   cr   STrr   rr   rs   dup_zz_hensel_step   s$   r   c              	   C   st  t |}t||}|dkr$t|||| | d |}t|| | |gS | }|d }	ttt|}
t|g| }|d|	 D ]}t	|t|| | |}q>t||	 | }||	d d D ]}t	|t|| | |}qZt
||| |\}}}t|| }t|| }t|| }t|| }td|
d D ]}t||||||||d \}}}}}qt| ||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,\ \dots,\ 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]_

    rf   r   rx   N)lenr   r=   gcdexrC   intr   _log2r   r   r   r   ranger   dup_zz_hensel_lift)prj   f_listlrl   rq   r   Fr   ro   r   r   f_ir   r   r   _rr   rr   rs   r     s0   




(r   c                 C   s(   ||d kr
|| }|sdS | | dkS )Nrx   Tr   rr   )fcrp   plrr   rr   rs   _test_plG  s
   r   c                    sv  t | }|dkr| gS ddlm} | d }t| |}t| |}tt|||d d|  | | }t|d d|  |d| d   }ttdt	| }	td|	 t
|	 }
g }td|
d D ];}||ro|| dkrpqc||}t| |}t|||sqct|||d }|||f t|dk st|dkr nqct|d	d
 d\}ttt
d| d }fdd|D }t| |||}tt|}t|}g d}}| }d| t|krt||D ] |dkrd} D ]
}||| d  }q|| }t|||s
qn-|g} D ]}t||| |}qt|||}t||d }|d }|r8|| dkr8q|g}t  |  }|dkr_|g} D ]}t||| |}qMt|||}|D ]}t||| |}qat|||}t||}t||}|| |kr|} fdd|D }t||d }t||d } || t| |} nq|d7 }d| t|ks|| g S )z4Factor primitive square-free polynomials in `Z[x]`. rf   r   )isprimerx            c                 S   s   t | d S )Nrf   )r   )xrr   rr   rs   <lambda>p  s    z#dup_zz_zassenhaus.<locals>.<lambda>)keyc                    s   g | ]}t | qS rr   )r   )rz   ff)r   rr   rs   
<listcomp>t      z%dup_zz_zassenhaus.<locals>.<listcomp>c                    s   g | ]}| vr|qS rr   rr   )rz   i)r   rr   rs   r         )r   sympy.ntheoryr   r:   r   r   r   r   r   r   _logr   convertr   r   r   ri   r   minr   setr`   r   r-   rC   rH   r<   )rj   rl   r   r   r   Ar   BCgammar   r   pxr   fsqfxfsqfr   modularr   sorted_Tr   rk   r   r   rp   r   r   r   T_SG_normH_normrr   )r   r   rs   dup_zz_zassenhausN  s   

*$









7r   c                 C   sr   t | |}t| |}t| dd |}|r5ddlm} |t|}| D ]}|| r4||d  r4 dS q%dS dS )z2Test irreducibility using Eisenstein's criterion. rf   Nr   	factorintrx   T)r   r   rE   r   r   r   keys)rj   rl   r   tce_fcr   e_ffr   rr   rr   rs   dup_zz_irreducible_p  s   

r   Fc                 C   s  |j rz|| }}t| ||} W n ty   Y dS w |js"dS t| |}t| |}|dks8|dkr:|dkr:dS |sQt| |\}}||jksO|| dfgkrQdS t	| }g g }	}
t
|ddD ]
}|	d| |  q`t
|d ddD ]
}|
d| |  qstt|	|}	tt|
|}
t|	t|
d||}|t||rt||}|| krdS t| |}	|t|	|rt|	|}	||	krt|	|rdS t||}t|||krt||rdS dS )ad  
    Efficiently test if ``f`` is a cyclotomic polynomial.

    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

    References
    ==========

    Bradford, Russell J., and James H. Davenport. "Effective tests for
    cyclotomic polynomials." In International Symposium on Symbolic and
    Algebraic Computation, pp. 244-251. Springer, Berlin, Heidelberg, 1988.

    Frf   r   r   T)is_QQget_ringr   r^   is_ZZr   r   dup_factor_listr   r   r   insertr/   r   r+   r9   is_negativer'   rO   dup_cyclotomic_prV   )rj   rl   irreducibleK0r   r   coeffrk   r   r   r   r   r   r   rr   rr   rs   r     sN   






r   c                 C   s\   ddl m} |j|j g}||  D ]\}}tt|||||}t|||d  |}q|S )z1Efficiently generate n-th cyclotomic polynomial. r   r   rf   )r   r   r   itemsr3   r    )r   rl   r   r   r   ro   rr   rr   rs   dup_zz_cyclotomic_poly  s   r   c                    s   ddl m}  j j gg}||  D ]*\} fdd|D }|| td|D ]} fdd|D }|| q,q|S )Nr   r   c                    s    g | ]}t t| | qS rr   )r3   r    )rz   r   rl   r   rr   rs   r   ,       z-_dup_cyclotomic_decompose.<locals>.<listcomp>rf   c                    s   g | ]}t | qS rr   )r    )rz   rp   r   rr   rs   r   0  r   )r   r   r   r   extendr   )r   rl   r   r   ro   Qr   rr   r   rs   _dup_cyclotomic_decompose&  s   
r   c                 C   s   t | |t| |}}t| dkrdS |dks|dvrdS tdd | dd D r,dS t| }t||}||s<|S g }td| |D ]}||vrP|| qE|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 cyclotomic decomposition of `f`,
    which makes this method much faster that any other direct factorization
    approach (e.g. Zassenhaus's).

    References
    ==========

    .. [1] [Weisstein09]_

    r   Nrf   )r   rf   c                 s   s    | ]}t |V  qd S )N)boolry   rr   rr   rs   r|   P  r}   z+dup_zz_cyclotomic_factor.<locals>.<genexpr>r   rx   )r   r   r   anyr   is_oneri   )rj   rl   lc_ftc_fr   r   r   r   rr   rr   rs   dup_zz_cyclotomic_factor6  s"   


r   c                 C   s   t | |\}}t|}t||dk r| t||}}|dkr#|g fS |dkr,||gfS tdr:t||r:||gfS d}tdrEt||}|du rNt||}|t|ddfS )z:Factor square-free (non-primitive) polynomials in `Z[x]`. r   rf   USE_IRREDUCIBLE_IN_FACTORNUSE_CYCLOTOMIC_FACTORF)multiple)	rH   r   r   r'   r[   r   r   r   rZ   )rj   rl   contr   r   rk   rr   rr   rs   dup_zz_factor_sqfb  s"   




r   c                 C   s  t dkr t| ddd }| \}}dd |D }|t|fS t| |\}}t|}t||dk r;| t||}}|dkrC|g fS |dkrN||dfgfS tdr^t	||r^||dfgfS t
||}d}td	rnt||}|du rwt||}t| ||}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))

    Examples
    ========

    Consider the 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]_

    rd   Nr   c                 S   s&   g | ]\}}|  d d d |fqS )Nr   )coeffs)rz   facexprr   rr   rs   r     s   & z!dup_zz_factor.<locals>.<listcomp>r   rf   r   r   )r   re   rn   rZ   rH   r   r   r'   r[   r   rV   r   r   rt   rX   )rj   rl   f_flintr   rk   r   r   r   rr   rr   rs   dup_zz_factor  s2   .




r   c                 C   sv   || g}| D ]-}t |}t|D ]}|dkr%|||}|| }|dks||r.  dS q|| q|dd S )z,Wang/EEZ: Compute a set of valid divisors.  rf   N)r   reversedgcdr   ri   )Ecsctrl   rm   rp   rq   rr   rr   rs   dmp_zz_wang_non_divisors  s   

r   c                    s   t t|  |d stdt |  |}t|s tdt|\}}t|r8| t|}}|d  fdd|D }	t|	||}
|
durW|||	fS td)z2Wang/EEZ: Test evaluation points for suitability. rf   zno luckc                    s   g | ]\}}t | qS rr   )rJ   )rz   r   r   r   rl   vrr   rs   r     s    z+dmp_zz_wang_test_points.<locals>.<listcomp>N)	rJ   r   r_   rS   rH   r   r   r'   r   )rj   r   r   r   ru   rl   r   r   r   r   Drr   r   rs   dmp_zz_wang_test_points  s   

r   c              	   C   s  g dgt | |d }}	}
|D ]R}t|
|}t||| }ttt |D ]6}d|| || }}\}}|| sH|| |d }}|| r;|dkr]t|t|||
||
|d}|	|< q'|| qt|	sjt	g g }}t
||D ]E\}}t|||
|}t||}||r|| }n|||}|| || }}t||||| }}t|||
|}|| || qt||r| ||fS g g }}t
||D ]\}}|t|||
| |t||d| qt| |t |d  ||} | ||fS )z0Wang/EEZ: Compute correct leading coefficients. r   rf   )r   r   r   r   r   r.   r0   ri   allr\   ziprJ   r   r   r=   r>   )rj   r   r   r   r   r   ru   rl   r   Jr   r   r   r   r   ro   r   r   r   CCHHr   ccr   CCCHHHrr   rr   rs   dmp_zz_wang_lead_coeffs  sF   
"








r  c              	   C   s  t | dkrK| \}}t||}t||}t||||\}}	}
t|||}t|	||}	t||||\}}t|	||||}	t||}t|	|}	||	g}|S | d g}
t| dd D ]}|
dt	||
d | qXg dgg}}t
| |
D ]\}}t||g|d g d|d|\}	}||	 || qsg ||d g }}t
|| D ]#\}}t||}t||}tt||||||}t||}|| q|S )z2Wang/EEZ: Solve univariate Diophantine equations. rx   r   rf   r   )r   r   r   r   r	   r   r   r   r   r-   r   dmp_zz_diophantineri   r
   )r   r   r   rl   r   r   rj   r   r   r   r   rp   rm   r   r   rq   rr   rr   rs   dup_zz_diophantine7  s:   




 



r	  c              	      s  |sDdd | D }t |}t|D ]0\}	}
|
sqt| ||	  }tt||D ]\}\}}t||
 }tt||  ||< q(q|S t|}t|  }|d |dd }}g g }}| D ]}|	t
||  |	t|||  q`t||| }d t|||| } fdd|D }t||D ]\}}t||| }qt| }t j| g| }t| }td|D ]}t|r n{t|| }t||d || }t|sHt|  |d  }t|||| }t|D ]\}	}tt|d | ||	< qtt||D ]\}	\}}t|| ||	< qt||D ]\}}t||| }q3t| }qŇ fdd|D }|S )	z4Wang/EEZ: Solve multivariate Diophantine equations. c                 S   s   g | ]}g qS rr   rr   rz   r   rr   rr   rs   r   j  s    z&dmp_zz_diophantine.<locals>.<listcomp>r   Nrf   c                    s   g | ]	}t |d  qS rf   )r   rz   r   )rl   r   rr   rs   r         r   c                    s   g | ]	}t | qS rr   )rD   r  )rl   r   ru   rr   rs   r     r  )r   	enumerater	  r   r=   rC   r)   r   r5   ri   r4   rK   r  r8   rD   r   r   r   r   r   r.   rL   r@   	factorialr   r*   )r   r   r   r   r   ru   rl   r   r   r   r   r   jr   r   r   r   r   r   rj   r   r   r   r   ro   rr   )rl   r   ru   r   rs   r  g  s\   5


 r  c              
   C   s  | gt ||d }}}	t|}tt|dd D ]\}
}t|d |||
 ||
 |}|dt|||	|
 | qtt| |dd }t	t
d|d ||D ]\}}}t||d }}|d|d  ||d d }}tt	||D ]&\}
\}}tt|||	|||d |}|gt|dd d|d | ||
< qwt|j| g||}t||}t|t|||||}t|||}t
d|D ]x}t||r npt||||}t||d ||||}t||d s;t||||d |d |}t||||||d |}tt	||D ]\}
\}}t|t|d|d ||||}t||||||
< q	t|t|||||}t||||}qqQt|||| krHt|S )z-Wang/EEZ: Parallel Hensel lifting algorithm. rf   Nr   rx   )r   listr  r   rK   r   rD   maxr   r   r   rJ   r   r   r   r   r,   r5   r   r   r.   rL   r@   r  r  r6   r\   )rj   r   LCr   r   ru   rl   r   r   r   r   r   r   r   r  r   wIr  r   r   r   r   r   djro   r   r   r   rr   rr   rs   dmp_zz_wang_hensel_lifting  sB    "&

 r  c              	      s2  ddl m} t|tt|  |d  \}}t| | } ||}	du r0|dkr.dndt g  jg| df\}
}}}z)t| |||| \}}}t	| \}}t
|}|dkr_| gW S |||||fg}W n	 tyq   Y nw td}td}td}t
||k rt|D ]r} fd	d
t|D }t||
vr|
t| nqzt| |||| \}}}W n	 ty   Y qw t	| \}}t
|}|dur||kr||k rg |}}nqn|}|dkr| g  S ||||||f t
||kr nq|7 t
||k sd\}}}|D ]"\}}}}}t| }|dur(||k r'|}|}n|}|d7 }q|| \}}}}}| }zt| |||||| \} }}t| ||||	| }W n tyq   tdrmt|| d  Y S tdw g }|D ] } t| | \}}  t| | rt| | } ||  qv|S )a`  
    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, \dots, 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   )	nextprimerf   Nrx   EEZ_NUMBER_OF_CONFIGSEEZ_NUMBER_OF_TRIESEEZ_MODULUS_STEPc                    s   g | ]
}  qS rr   rr   r
  rl   modrandintrr   rs   r   "  s    zdmp_zz_wang.<locals>.<listcomp>)Nr   r   EEZ_RESTART_IF_NEEDEDz3we need to restart algorithm with better parameters)r   r  r   dmp_zz_factorr   r   r   zeror   r   r   r_   r[   r   tupleaddri   r:   r  r  r\   dmp_zz_wangrI   r   r   r(   )rj   ru   rl   r  seedr  r   r   r   r   historyconfigsr   rq   r   r   r   r   r   eez_num_configseez_num_trieseez_mod_steprrs_norms_argr   _s_normorig_fr  rk   rm   rr   r  rs   r$    s   

%



r$  c           	      C   s  |st | |S t| |r|jg fS t| ||\}}t|||dk r+| t|||}}tdd t||D r;|g fS t|||\}}g }t	||dkr_t
|||}t|||}t| |||}t||d |d D ]\}}|d|g|f qit| || |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, \dots, 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       | ]}|d kV  qdS r   Nrr   rz   r   rr   rr   rs   r|     r}   z dmp_zz_factor.<locals>.<genexpr>rf   )r   r   r!  rI   r   r(   r   r   rP   r   rW   r$  rv   r   r   rY   rZ   )	rj   ru   rl   r   r   r   rk   r   ro   rr   rr   rs   r   m  s&   $


r   c                    sJ      t|  } t| \}} fdd|D } |}||fS )z>Factor univariate polynomials into irreducibles in `QQ_I[x]`. c                    s    g | ]\}}t | |fqS rr   )r   rz   r   r   r   K1rr   rs   r     r   z#dup_qq_i_factor.<locals>.<listcomp>)as_AlgebraicFieldr   r   r   )rj   r   r   rk   rr   r4  rs   dup_qq_i_factor  s   r7  c                 C   s   |  }t| ||} t| |\}}g }|D ]*\}}t||\}}	t|	||}
t|
d|\}}|||  ||  }|||f q|}|||}||fS )z>Factor univariate polynomials into irreducibles in `ZZ_I[x]`. r   )	get_fieldr   r7  rA   rI   ri   r   )rj   r   r5  r   rk   new_factorsr   r   	fac_denomfac_numfac_num_ZZ_Icontentfac_primrr   rr   rs   dup_zz_i_factor  s   r?  c                    sP      t|  } t| \}} fdd|D } |}||fS )z@Factor multivariate polynomials into irreducibles in `QQ_I[X]`. c                    s"   g | ]\}}t | |fqS rr   )r   r3  r   r5  ru   rr   rs   r     s   " z#dmp_qq_i_factor.<locals>.<listcomp>)r6  r   dmp_factor_listr   )rj   ru   r   r   rk   rr   r@  rs   dmp_qq_i_factor  s   rB  c                 C   s   |  }t| |||} t| ||\}}g }|D ],\}}t|||\}	}
t|
|||}t|||\}}|||  |	|  }|||f q|}|||}||fS )z@Factor multivariate polynomials into irreducibles in `ZZ_I[X]`. )r8  r   rB  rB   rI   ri   r   )rj   ru   r   r5  r   rk   r9  r   r   r:  r;  r<  r=  r>  rr   rr   rs   dmp_zz_i_factor  s   rC  c                 C   s  t | t| |}}t| |} |dkr|g fS |dkr"|| dfgfS t| || } }t| |\}}}t||j}t|dkrI|| |t |  fgfS ||j }	t	|D ] \}
\}}t
||j|}t|||\}}}t||	|}|||
< qRt|||}t|| ||fS )aN	  Factor univariate polynomials over algebraic number fields.

    The domain `K` must be an algebraic number field `k(a)` (see :ref:`QQ(a)`).

    Examples
    ========

    First define the algebraic number field `K = \mathbb{Q}(\sqrt{2})`:

    >>> from sympy import QQ, sqrt
    >>> from sympy.polys.factortools import dup_ext_factor
    >>> K = QQ.algebraic_field(sqrt(2))

    We can now factorise the polynomial `x^2 - 2` over `K`:

    >>> p = [K(1), K(0), K(-2)] # x^2 - 2
    >>> p1 = [K(1), -K.unit]    # x - sqrt(2)
    >>> p2 = [K(1), +K.unit]    # x + sqrt(2)
    >>> dup_ext_factor(p, K) == (K.one, [(p1, 1), (p2, 1)])
    True

    Usually this would be done at a higher level:

    >>> from sympy import factor
    >>> from sympy.abc import x
    >>> factor(x**2 - 2, extension=sqrt(2))
    (x - sqrt(2))*(x + sqrt(2))

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

    Uses Trager's algorithm. In particular this function is algorithm
    ``alg_factor`` from [Trager76]_.

    If `f` is a polynomial in `k(a)[x]` then its norm `g(x)` is a polynomial in
    `k[x]`. If `g(x)` is square-free and has irreducible factors `g_1(x)`,
    `g_2(x)`, `\cdots` then the irreducible factors of `f` in `k(a)[x]` are
    given by `f_i(x) = \gcd(f(x), g_i(x))` where the GCD is computed in
    `k(a)[x]`.

    The first step in Trager's algorithm is to find an integer shift `s` so
    that `f(x-sa)` has square-free norm. Then the norm is factorized in `k[x]`
    and the GCD of (shifted) `f` with each factor gives the shifted factors of
    `f`. At the end the shift is undone to recover the unshifted factors of `f`
    in `k(a)[x]`.

    The algorithm reduces the problem of factorization in `k(a)[x]` to
    factorization in `k[x]` with the main additional steps being to compute the
    norm (a resultant calculation in `k[x,y]`) and some polynomial GCDs in
    `k(a)[x]`.

    In practice in SymPy the base field `k` will be the rationals :ref:`QQ` and
    this function factorizes a polynomial with coefficients in an algebraic
    number field  like `\mathbb{Q}(\sqrt{2})`.

    See Also
    ========

    dmp_ext_factor:
        Analogous function for multivariate polynomials over ``k(a)``.
    dup_sqf_norm:
        Subroutine ``sqfr_norm`` also from [Trager76]_.
    sympy.polys.polytools.factor:
        The high-level function that ultimately uses this function as needed.
    r   rf   )r   r   rF   rV   rT   dup_factor_list_includedomr   unitr  r   rQ   rM   rt   rX   )rj   rl   r   r   r   r   r   rq   rk   r   r   rn   r   r   rr   rr   rs   dup_ext_factor  s(   B



rG  c                    s  |st |  S t| | }t| | } tdd t| |D r#|g fS t| | | } }t| | \}}}t|| j}t	|dkrF| g}n1t
|D ],\}	\}
}t|
| j }t||| \}}} fdd|D }t||| }|||	< qJt||| }t||| ||fS )a  Factor multivariate polynomials over algebraic number fields.

    The domain `K` must be an algebraic number field `k(a)` (see :ref:`QQ(a)`).

    Examples
    ========

    First define the algebraic number field `K = \mathbb{Q}(\sqrt{2})`:

    >>> from sympy import QQ, sqrt
    >>> from sympy.polys.factortools import dmp_ext_factor
    >>> K = QQ.algebraic_field(sqrt(2))

    We can now factorise the polynomial `x^2 y^2 - 2` over `K`:

    >>> p = [[K(1),K(0),K(0)], [], [K(-2)]] # x**2*y**2 - 2
    >>> p1 = [[K(1),K(0)], [-K.unit]]       # x*y - sqrt(2)
    >>> p2 = [[K(1),K(0)], [+K.unit]]       # x*y + sqrt(2)
    >>> dmp_ext_factor(p, 1, K) == (K.one, [(p1, 1), (p2, 1)])
    True

    Usually this would be done at a higher level:

    >>> from sympy import factor
    >>> from sympy.abc import x, y
    >>> factor(x**2*y**2 - 2, extension=sqrt(2))
    (x*y - sqrt(2))*(x*y + sqrt(2))

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

    This is Trager's algorithm for multivariate polynomials. In particular this
    function is algorithm ``alg_factor`` from [Trager76]_.

    See :func:`dup_ext_factor` for explanation.

    See Also
    ========

    dup_ext_factor:
        Analogous function for univariate polynomials over ``k(a)``.
    dmp_sqf_norm:
        Multivariate version of subroutine ``sqfr_norm`` also from [Trager76]_.
    sympy.polys.polytools.factor:
        The high-level function that ultimately uses this function as needed.
    c                 s   r0  r1  rr   r2  rr   rr   rs   r|     r}   z!dmp_ext_factor.<locals>.<genexpr>rf   c                    s   g | ]}| j  qS rr   )rF  )rz   sirl   rr   rs   r     r   z"dmp_ext_factor.<locals>.<listcomp>)rG  r   rG   r   r   rW   rU   dmp_factor_list_includerE  r   r  r   rR   rN   rv   rY   )rj   ru   rl   r   r   r   r   rq   rk   r   rn   r   r   r   rm   rr   rI  rs   dmp_ext_factorT  s(   /

rK  c                 C   s`   t | ||j} t| |j|j\}}t|D ]\}\} }t | |j||f||< q|||j|fS )z2Factor univariate polynomials over finite fields. )r   rE  r   r  r  r   )rj   rl   r   rk   r   ro   rr   rr   rs   dup_gf_factor  s
   rL  c                 C   s   t d)z4Factor multivariate polynomials over finite fields. z+multivariate polynomials over finite fields)NotImplementedError)rj   ru   rl   rr   rr   rs   dmp_gf_factor  s   rN  c                 C   s4  t | |\}} t| |\}} |jrt| |\}}n|jr$t| |\}}n|jr/t| |\}}n|jr:t	| |\}}n|j
sK|| }}t| ||} nd}|jrc| }t| ||\}} t| ||} n|}|jrpt| |\}}n7|jrt| d|\} }	t| |	|j\}}t|D ]\}
\} }t| |	||f||
< q|||j}ntd| |jrt|D ]\}
\} }t| |||f||
< q|||}|||}|rt|D ]'\}
\} }t| |}t| ||} t| ||} | |f||
< |||||}q|||}|}|r|d|j |j!g|f || t"|fS );Factor univariate polynomials into irreducibles in `K[x]`. Nr   #factorization not supported over %s)#r%   rH   is_FiniteFieldrL  is_AlgebraicrG  is_GaussianRingr?  is_GaussianFieldr7  is_Exact	get_exactr   is_Fieldr   rA   r   r   is_Polyr#   rA  rE  r  r$   r   r]   quor:   r?   mulpowr   r   r!  rZ   )rj   r   r  r   r   rk   
K0_inexactrl   denomru   r   ro   max_normrr   rr   rs   r     sZ   
r   c                 C   sT   t | |\}}|st|gdfgS t|d d ||}||d d fg|dd  S )rO  rf   r   N)r   r   r=   )rj   rl   r   rk   r   rr   rr   rs   rD    s
   rD  c                 C   s  |st | |S t| ||\}} t| ||\}} |jr$t| ||\}}n|jr1t| ||\}}n	|jr=t| ||\}}n|j	rIt
| ||\}}n|js[|| }}t| |||} nd}|jru| }t| |||\}	} t| |||} n|}|jrt| ||\}
} }t| ||\}}t|D ]\}\} }t| |
|||f||< qn7|jrt| ||\} }t| ||j\}}t|D ]\}\} }t| |||f||< q|||j}ntd| |jr:t|D ]\}\} }t| ||||f||< q|||}|||	}|r:t|D ]+\}\} }t| ||}t| |||} t| |||} | |f||< | ||!||}q|||}|}tt"|D ]%\}}|sIq@d||  d d|  |j#i}|$dt%||||f q@|| t&|fS )=Factor multivariate polynomials into irreducibles in `K[X]`. NrP  )r   r  r   )'r   r&   rI   rQ  rN  rR  rK  rS  rC  rT  rB  rU  rV  r   rW  r   rB   r   r!   r   r  r"   rX  r#   rA  rE  r$   r   r]   rY  r;   r@   rZ  r[  r   r   r   r   rZ   )rj   ru   r   r  r   r   rk   r\  rl   r]  levelsr   r   ro   r^  r  termrr   rr   rs   rA     sl   
rA  c                 C   sf   |st | |S t| ||\}}|st||dfgS t|d d |||}||d d fg|dd  S )r_  rf   r   N)rD  rA  r   r>   )rj   ru   rl   r   rk   r   rr   rr   rs   rJ  M  s   
rJ  c                 C   s   t | d|S )z_
    Returns ``True`` if a univariate polynomial ``f`` has no factors
    over its domain.
    r   )dmp_irreducible_p)rj   rl   rr   rr   rs   dup_irreducible_p[  s   rc  c                 C   s<   t | ||\}}|sdS t|dkrdS |d \}}|dkS )za
    Returns ``True`` if a multivariate polynomial ``f`` has no factors
    over its domain.
    Trf   Fr   )rA  r   )rj   ru   rl   r   rk   ro   rr   rr   rs   rb  c  s   rb  )F)NN)__doc__sympy.external.gmpyr   sympy.core.randomr   sympy.polys.galoistoolsr   r   r   r   r   r	   r
   r   r   r   r   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&   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@   sympy.polys.densetoolsrA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   sympy.polys.euclidtoolsrP   rQ   rR   sympy.polys.sqfreetoolsrS   rT   rU   rV   rW   rX   rY   sympy.polys.polyutilsrZ   sympy.polys.polyconfigr[   sympy.polys.polyerrorsr\   r]   r^   r_   sympy.utilitiesr`   mathra   r   rb   r   rc   r   rd   re   rt   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r	  r  r  r$  r   r7  r?  rB  rC  rG  rK  rL  rN  r   rD  rA  rJ  rc  rb  rr   rr   rr   rs   <module>   sn    4hpD
$
<	99i
S,T60D
4 CbNBM