
    wg                     D   d Z ddlmZmZ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 dUd	Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd ZdVdZd Z dVdZ!d Z"d Z#d Z$d Z%d Z&d Z'd Z(d Z)d Z*d  Z+d! Z,d" Z-d# Z.d$ Z/d% Z0d& Z1d' Z2d( Z3d) Z4d* Z5d+ Z6d, Z7d- Z8d. Z9d/ Z:d0 Z;d1 Z<d2 Z=d3 Z>d4 Z?d5 Z@d6 ZAd7 ZBd8 ZCd9 ZDd: ZEd; ZFd< ZGd= ZHeGeHd>ZId? ZJd@ ZKdA ZLdWdBZMdC ZNdD ZOdE ZPdF ZQdG ZRdH ZSdI ZTdJ ZUdK ZVePeUeVdLZWdUdMZXdN ZYdO ZZdP Z[dQ Z\dUdRZ]dXdSZ^dT Z_y)YzADense univariate polynomials with coefficients in Galois fields.     )ceilsqrtprod)uniform_randint)
SYMPY_INTSMPZinvert)query)ExactQuotientFailed)_sort_factorsNc                     t        ||j                        }|j                  }t        | |      D ].  \  }}||z  }|j	                  ||      \  }}	}	||||z  |z  z  z  }0 ||z  S )aH  
    Chinese Remainder Theorem.

    Given a set of integer residues ``u_0,...,u_n`` and a set of
    co-prime integer moduli ``m_0,...,m_n``, returns an integer
    ``u``, such that ``u = u_i mod m_i`` for ``i = ``0,...,n``.

    Examples
    ========

    Consider a set of residues ``U = [49, 76, 65]``
    and a set of moduli ``M = [99, 97, 95]``. Then we have::

       >>> from sympy.polys.domains import ZZ
       >>> from sympy.polys.galoistools import gf_crt

       >>> gf_crt([49, 76, 65], [99, 97, 95], ZZ)
       639985

    This is the correct result because::

       >>> [639985 % m for m in [99, 97, 95]]
       [49, 76, 65]

    Note: this is a low-level routine with no error checking.

    See Also
    ========

    sympy.ntheory.modular.crt : a higher level crt routine
    sympy.ntheory.modular.solve_congruence

    start)r   onezerozipgcdex)
UMKpvumes_s
             \/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/polys/galoistools.pygf_crtr       sv    D 	QaeeA	AAq	 1F''!Q-1a	Q!a[
 q5L    c                     g g }}t        | |j                        }| D ]@  }|j                  ||z         |j                  |j                  |d   |      d   |z         B |||fS )aP  
    First part of the Chinese Remainder Theorem.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_crt, gf_crt1, gf_crt2
    >>> U = [49, 76, 65]
    >>> M = [99, 97, 95]

    The following two codes have the same result.

    >>> gf_crt(U, M, ZZ)
    639985

    >>> p, E, S = gf_crt1(M, ZZ)
    >>> gf_crt2(U, M, p, E, S, ZZ)
    639985

    However, it is faster when we want to fix ``M`` and
    compute for multiple U, i.e. the following cases:

    >>> p, E, S = gf_crt1(M, ZZ)
    >>> Us = [[49, 76, 65], [23, 42, 67]]
    >>> for U in Us:
    ...     print(gf_crt2(U, M, p, E, S, ZZ))
    639985
    236237

    See Also
    ========

    sympy.ntheory.modular.crt1 : a higher level crt routine
    sympy.polys.galoistools.gf_crt
    sympy.polys.galoistools.gf_crt2

    r   r   )r   r   appendr   )r   r   ESr   r   s         r   gf_crt1r'   9   so    N rqAQaeeA +	a	2"1%)*+ a7Nr!   c                 p    |j                   }t        | |||      D ]  \  }}}	}
||	||
z  |z  z  z  } ||z  S )a  
    Second part of the Chinese Remainder Theorem.

    See ``gf_crt1`` for usage.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_crt2

    >>> U = [49, 76, 65]
    >>> M = [99, 97, 95]
    >>> p = 912285
    >>> E = [9215, 9405, 9603]
    >>> S = [62, 24, 12]

    >>> gf_crt2(U, M, p, E, S, ZZ)
    639985

    See Also
    ========

    sympy.ntheory.modular.crt2 : a higher level crt routine
    sympy.polys.galoistools.gf_crt
    sympy.polys.galoistools.gf_crt1

    )r   r   )r   r   r   r%   r&   r   r   r   r   r   r   s              r   gf_crt2r)   j   sO    : 	
A!Q1o 
1a	Q!a[ q5Lr!   c                      | |dz  k  r| S | |z
  S )z
    Coerce ``a mod p`` to an integer in the range ``[-p/2, p/2]``.

    Examples
    ========

    >>> from sympy.polys.galoistools import gf_int

    >>> gf_int(2, 7)
    2
    >>> gf_int(5, 7)
    -2

        )ar   s     r   gf_intr.      s     	AF{1ur!   c                     t        |       dz
  S )z
    Return the leading degree of ``f``.

    Examples
    ========

    >>> from sympy.polys.galoistools import gf_degree

    >>> gf_degree([1, 1, 2, 0])
    3
    >>> gf_degree([])
    -1

       len)fs    r   	gf_degreer4      s     q6A:r!   c                 (    | s|j                   S | d   S )z
    Return the leading coefficient of ``f``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_LC

    >>> gf_LC([3, 0, 1], ZZ)
    3

    r   r   r3   r   s     r   gf_LCr8      s     vvtr!   c                 (    | s|j                   S | d   S )z
    Return the trailing coefficient of ``f``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_TC

    >>> gf_TC([3, 0, 1], ZZ)
    1

    r#   r6   r7   s     r   gf_TCr:      s     vvur!   c                 B    | r| d   r| S d}| D ]  }|r n|dz  } | |d S )z
    Remove leading zeros from ``f``.


    Examples
    ========

    >>> from sympy.polys.galoistools import gf_strip

    >>> gf_strip([0, 0, 0, 3, 0, 1])
    [3, 0, 1]

    r   r0   Nr,   )r3   kcoeffs      r   gf_stripr>      sB     !	A FA	 QR5Lr!   c                 D    t        | D cg c]  }||z  	 c}      S c c}w )z
    Reduce all coefficients modulo ``p``.

    Examples
    ========

    >>> from sympy.polys.galoistools import gf_trunc

    >>> gf_trunc([7, -2, 3], 5)
    [2, 3, 3]

    )r>   )r3   r   r-   s      r   gf_truncr@      s!     Q(a!e())(s   c                 @    t        t        t        ||             |      S )z
    Normalize all coefficients in ``K``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_normal

    >>> gf_normal([5, 10, 21, -3], 5, ZZ)
    [1, 2]

    )r@   listmap)r3   r   r   s      r   	gf_normalrD   
  s     DQOQ''r!   c                 |   t        | j                               g }}t        |t              rAt	        |dd      D ]0  }|j                  | j                  ||j                        |z         2 nE|\  }t	        |dd      D ]1  }|j                  | j                  |f|j                        |z         3 t        ||      S )a  
    Create a ``GF(p)[x]`` polynomial from a dict.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_from_dict

    >>> gf_from_dict({10: ZZ(4), 4: ZZ(33), 0: ZZ(-1)}, 5, ZZ)
    [4, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4]

    r#   )	maxkeys
isinstancer   ranger$   getr   r@   )r3   r   r   nhr<   s         r   gf_from_dictrM     s     qvvx="qA!Z q"b! 	+AHHQUU1aff%)*	+ q"b! 	.AHHQUUA4(1,-	. Aq>r!   c                     t        |       i }}t        d|dz         D ]'  }|rt        | ||z
     |      }n| ||z
     }|s#|||<   ) |S )aA  
    Convert a ``GF(p)[x]`` polynomial to a dict.

    Examples
    ========

    >>> from sympy.polys.galoistools import gf_to_dict

    >>> gf_to_dict([4, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4], 5)
    {0: -1, 4: -2, 10: -1}
    >>> gf_to_dict([4, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4], 5, symmetric=False)
    {0: 4, 4: 3, 10: 4}

    r   r0   )r4   rI   r.   )r3   r   	symmetricrK   resultr<   r-   s          r   
gf_to_dictrQ   7  sa     !bvA1a!e_ qQx#A!a%AF1I Mr!   c                     t        | |      S )z
    Create a ``GF(p)[x]`` polynomial from ``Z[x]``.

    Examples
    ========

    >>> from sympy.polys.galoistools import gf_from_int_poly

    >>> gf_from_int_poly([7, -2, 3], 5)
    [2, 3, 3]

    )r@   )r3   r   s     r   gf_from_int_polyrS   T  s     Aq>r!   c                 H    |r| D cg c]  }t        ||       c}S | S c c}w )a  
    Convert a ``GF(p)[x]`` polynomial to ``Z[x]``.


    Examples
    ========

    >>> from sympy.polys.galoistools import gf_to_int_poly

    >>> gf_to_int_poly([2, 3, 3], 5)
    [2, -2, -2]
    >>> gf_to_int_poly([2, 3, 3], 5, symmetric=False)
    [2, 3, 3]

    )r.   )r3   r   rO   cs       r   gf_to_int_polyrV   d  s(      '(*!1** +s   c                 4    | D cg c]  }| |z  
 c}S c c}w )z
    Negate a polynomial in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_neg

    >>> gf_neg([3, 2, 1, 0], 5, ZZ)
    [2, 3, 4, 0]

    r,   )r3   r   r   r=   s       r   gf_negrX   z  s     &'(EeVaZ(((s   c                 d    | s||z  }n"| d   |z   |z  }t        |       dkD  r	| dd |gz   S |sg S |gS )a  
    Compute ``f + a`` where ``f`` in ``GF(p)[x]`` and ``a`` in ``GF(p)``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_add_ground

    >>> gf_add_ground([3, 2, 4], 2, 5, ZZ)
    [3, 2, 1]

    r#   r0   Nr1   r3   r-   r   r   s       r   gf_add_groundr[     sM     ErUQY!Oq6A:Sb6QC<	s
r!   c                 f    | s| |z  }n"| d   |z
  |z  }t        |       dkD  r	| dd |gz   S |sg S |gS )a  
    Compute ``f - a`` where ``f`` in ``GF(p)[x]`` and ``a`` in ``GF(p)``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_sub_ground

    >>> gf_sub_ground([3, 2, 4], 2, 5, ZZ)
    [3, 2, 2]

    r#   r0   Nr1   rZ   s       r   gf_sub_groundr]     sO     BFrUQY!Oq6A:Sb6QC<	s
r!   c                 @    |sg S | D cg c]
  }||z  |z   c}S c c}w )a  
    Compute ``f * a`` where ``f`` in ``GF(p)[x]`` and ``a`` in ``GF(p)``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_mul_ground

    >>> gf_mul_ground([3, 2, 4], 2, 5, ZZ)
    [1, 4, 3]

    r,   )r3   r-   r   r   bs        r   gf_mul_groundr`     s(     	$%'q!A#'''s   c                 >    t        | |j                  ||      ||      S )a  
    Compute ``f/a`` where ``f`` in ``GF(p)[x]`` and ``a`` in ``GF(p)``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_quo_ground

    >>> gf_quo_ground(ZZ.map([3, 2, 4]), ZZ(2), 5, ZZ)
    [4, 1, 2]

    )r`   r
   rZ   s       r   gf_quo_groundrb     s     AHHQNAq11r!   c                 \   | s|S |s| S t        |       }t        |      }||k(  r.t        t        | |      D cg c]  \  }}||z   |z   c}}      S t        ||z
        }||kD  r| d| | |d } }	n
|d| ||d }}	|	t        | |      D cg c]  \  }}||z   |z   c}}z   S c c}}w c c}}w )z
    Add polynomials in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_add

    >>> gf_add([3, 2, 4], [2, 2, 2], 5, ZZ)
    [4, 1]

    N)r4   r>   r   abs
r3   gr   r   dfdgr-   r_   r<   rL   s
             r   gf_addri     s     	1B	1B	Rx#a)=$!Q1q5A+=>>RL7Ra5!AB%qARa5!AB%qASAY8TQa!eq[888 > 9s   B"

B(c                    |s| S | st        |||      S t        |       }t        |      }||k(  r.t        t        | |      D cg c]  \  }}||z
  |z   c}}      S t	        ||z
        }||kD  r| d| | |d } }	nt        |d| ||      ||d }}	|	t        | |      D cg c]  \  }}||z
  |z   c}}z   S c c}}w c c}}w )z
    Subtract polynomials in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_sub

    >>> gf_sub([3, 2, 4], [2, 2, 2], 5, ZZ)
    [1, 0, 2]

    N)rX   r4   r>   r   rd   re   s
             r   gf_subrk     s     aA	1B	1B	Rx#a)=$!Q1q5A+=>>RL7Ra5!AB%qA!BQ%A&!"qASAY8TQa!eq[888 > 9s   B8
 B>c                 (   t        |       }t        |      }||z   }dg|dz   z  }t        d|dz         D ]R  }|j                  }	t        t        d||z
        t	        ||      dz         D ]  }
|	| |
   |||
z
     z  z  }	 |	|z  ||<   T t        |      S )z
    Multiply polynomials in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_mul

    >>> gf_mul([3, 2, 4], [2, 2, 2], 5, ZZ)
    [1, 0, 3, 2, 3]

    r   r0   r4   rI   r   rF   minr>   )r3   rf   r   r   rg   rh   dhrL   ir=   js              r   gf_mulrr   .  s     
1B	1B	bB	
R!VA1b1f s1a"f~s1bzA~6 	#AQqT!AE(]"E	# qy! A;r!   c                 t   t        |       }d|z  }dg|dz   z  }t        d|dz         D ]  }|j                  }t        d||z
        }t	        ||      }	|	|z
  dz   }
||
dz  z   dz
  }	t        ||	dz         D ]  }|| |   | ||z
     z  z  } ||z  }|
dz  r| |	dz      }||dz  z  }||z  ||<    t        |      S )z
    Square polynomials in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_sqr

    >>> gf_sqr([3, 2, 4], 5, ZZ)
    [4, 2, 3, 1, 1]

    r+   r   r0   rm   )r3   r   r   rg   ro   rL   rp   r=   jminjmaxrK   rq   elems                r   gf_sqrrw   M  s     
1B	
2B	
R!VA1b1f 1a"f~1bz4K!Oa1f}q tTAX& 	#AQqT!AE(]"E	# 	q5TAX;DT1WEqy!'* A;r!   c           	      6    t        | t        ||||      ||      S )a  
    Returns ``f + g*h`` where ``f``, ``g``, ``h`` in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_add_mul
    >>> gf_add_mul([3, 2, 4], [2, 2, 2], [1, 4], 5, ZZ)
    [2, 3, 2, 2]
    )ri   rr   r3   rf   rL   r   r   s        r   
gf_add_mulrz   x  s      !VAq!Q'A..r!   c           	      6    t        | t        ||||      ||      S )a  
    Compute ``f - g*h`` where ``f``, ``g``, ``h`` in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_sub_mul

    >>> gf_sub_mul([3, 2, 4], [2, 2, 2], [1, 4], 5, ZZ)
    [3, 3, 2, 1]

    )rk   rr   ry   s        r   
gf_sub_mulr|     s      !VAq!Q'A..r!   c                     t        | t              r| \  }} n|j                  }|g}| D ]!  \  }}t        ||||      }t	        ||||      }# |S )a  
    Expand results of :func:`~.factor` in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_expand

    >>> gf_expand([([3, 2, 4], 1), ([2, 2], 2), ([3, 1], 3)], 5, ZZ)
    [4, 3, 0, 3, 0, 1, 4, 1]

    )rH   tupler   gf_powrr   )Fr   r   lcrf   r3   r<   s          r   	gf_expandr     sa     !UAUU	A 11aA1aA Hr!   c                    t        |       }t        |      }|st        d      ||k  rg | fS |j                  |d   |      }t        |       ||z
  |dz
  }	}}t	        d|dz         D ]^  }
||
   }t	        t        d||
z
        t        ||
z
  |	      dz         D ]  }|||
|z   |z
     |||z
     z  z  } |
|k  r||z  }||z  ||
<   ` |d|dz    t        ||dz   d       fS )a	  
    Division with remainder in ``GF(p)[x]``.

    Given univariate polynomials ``f`` and ``g`` with coefficients in a
    finite field with ``p`` elements, returns polynomials ``q`` and ``r``
    (quotient and remainder) such that ``f = q*g + r``.

    Consider polynomials ``x**3 + x + 1`` and ``x**2 + x`` in GF(2)::

       >>> from sympy.polys.domains import ZZ
       >>> from sympy.polys.galoistools import gf_div, gf_add_mul

       >>> gf_div(ZZ.map([1, 0, 1, 1]), ZZ.map([1, 1, 0]), 2, ZZ)
       ([1, 1], [1])

    As result we obtained quotient ``x + 1`` and remainder ``1``, thus::

       >>> gf_add_mul(ZZ.map([1]), ZZ.map([1, 1]), ZZ.map([1, 1, 0]), 2, ZZ)
       [1, 0, 1, 1]

    References
    ==========

    .. [1] [Monagan93]_
    .. [2] [Gathen99]_

    polynomial divisionr   r0   N)r4   ZeroDivisionErrorr
   rB   rI   rF   rn   r>   r3   rf   r   r   rg   rh   invrL   dqdrrp   r=   rq   s                r   gf_divr     s   8 
1B	1B 566	b1u
((1Q4
CQb"q&2rA1b1f 	!s1b1f~s262':; 	/AQq1urz]QrAvY..E	/ 7SLEqy!	 Wb1f:x"q&'
+++r!   c                 $    t        | |||      d   S )z
    Compute polynomial remainder in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_rem

    >>> gf_rem(ZZ.map([1, 0, 1, 1]), ZZ.map([1, 1, 0]), 2, ZZ)
    [1]

    r0   )r   r3   rf   r   r   s       r   gf_remr     s     !Q1a  r!   c                    t        |       }t        |      }|st        d      ||k  rg S |j                  |d   |      }| dd ||z
  |dz
  }	}}t        d|dz         D ]W  }
||
   }t        t	        d||
z
        t        ||
z
  |	      dz         D ]  }|||
|z   |z
     |||z
     z  z  } ||z  |z  ||
<   Y |d|dz    S )aG  
    Compute exact quotient in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_quo

    >>> gf_quo(ZZ.map([1, 0, 1, 1]), ZZ.map([1, 1, 0]), 2, ZZ)
    [1, 1]
    >>> gf_quo(ZZ.map([1, 0, 3, 2, 3]), ZZ.map([2, 2, 2]), 5, ZZ)
    [3, 2, 4]

    r   r   Nr0   )r4   r   r
   rI   rF   rn   r   s                r   gf_quor     s      
1B	1B 566	b	
((1Q4
C!b2grAv2rA1b1f !!s1b1f~s262':; 	/AQq1urz]QrAvY..E	/ q !! Wb1f:r!   c                 D    t        | |||      \  }}|s|S t        | |      )a  
    Compute polynomial quotient in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_exquo

    >>> gf_exquo(ZZ.map([1, 0, 3, 2, 3]), ZZ.map([2, 2, 2]), 5, ZZ)
    [3, 2, 4]

    >>> gf_exquo(ZZ.map([1, 0, 1, 1]), ZZ.map([1, 1, 0]), 2, ZZ)
    Traceback (most recent call last):
    ...
    ExactQuotientFailed: [1, 1, 0] does not divide [1, 0, 1, 1]

    )r   r   )r3   rf   r   r   qrs         r   gf_exquor   "  s-    & !Q1DAq!!Q''r!   c                 0    | s| S | |j                   g|z  z   S )z
    Efficiently multiply ``f`` by ``x**n``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_lshift

    >>> gf_lshift([3, 2, 4], 4, ZZ)
    [3, 2, 4, 0, 0, 0, 0]

    r6   r3   rK   r   s      r   	gf_lshiftr   =  s      AFF8A:~r!   c                 &    |s| g fS | d|  | | d fS )z
    Efficiently divide ``f`` by ``x**n``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_rshift

    >>> gf_rshift([1, 2, 3, 4, 0], 3, ZZ)
    ([1, 2], [3, 4, 0])

    Nr,   r   s      r   	gf_rshiftr   Q  s*     "u1"vq!v~r!   c                     |s|j                   gS |dk(  r| S |dk(  rt        | ||      S |j                   g}	 |dz  rt        || ||      }|dz  }|dz  }|s	 |S t        | ||      } 0)z
    Compute ``f**n`` in ``GF(p)[x]`` using repeated squaring.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_pow

    >>> gf_pow([3, 2, 4], 3, 5, ZZ)
    [2, 4, 4, 2, 2, 1, 4]

    r0   r+   )r   rw   rr   )r3   rK   r   r   rL   s        r   r   r   e  s     w	
a	
aaA	
A
q5q!Q"AFA	a H 1aO r!   c                    t        |       }|dk(  rg S dg|z  }dg|d<   ||k  r7t        d|      D ]&  }t        ||dz
     ||      }t        || ||      ||<   ( |S |dkD  rgt	        |j
                  |j                  g|| ||      |d<   t        d|      D ]0  }t        ||dz
     |d   ||      ||<   t        ||   | ||      ||<   2 |S )ah  
    return the list of ``x**(i*p) mod g in Z_p`` for ``i = 0, .., n - 1``
    where ``n = gf_degree(g)``

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_frobenius_monomial_base
    >>> g = ZZ.map([1, 0, 2, 1])
    >>> gf_frobenius_monomial_base(g, 5, ZZ)
    [[1], [4, 4, 2], [1, 2]]

    r   r0   r+   )r4   rI   r   r   
gf_pow_modr   r   rr   )rf   r   r   rK   r_   rp   mons          r   gf_frobenius_monomial_baser     s     	!AAv		
AA3AaD1uq! 	(AAa!eHa+C#q!Q'AaD	( H 
Q155!&&/1aA6!q! 	)A!AE(AaD!Q/AaD!A$1a(AaD	) Hr!   c                     t        |      }t        |       |k\  rt        | |||      } | sg S t        |       }| d   g}t        d|dz         D ]'  }t        ||   | ||z
     ||      }	t	        ||	||      }) |S )aS  
    compute gf_pow_mod(f, p, g, p, K) using the Frobenius map

    Parameters
    ==========

    f, g : polynomials in ``GF(p)[x]``
    b : frobenius monomial base
    p : prime number
    K : domain

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_frobenius_monomial_base, gf_frobenius_map
    >>> f = ZZ.map([2, 1, 0, 1])
    >>> g = ZZ.map([1, 0, 2, 1])
    >>> p = 5
    >>> b = gf_frobenius_monomial_base(g, p, ZZ)
    >>> r = gf_frobenius_map(f, g, b, p, ZZ)
    >>> gf_frobenius_map(f, g, b, p, ZZ)
    [4, 0, 3]
    r#   r0   )r4   r   rI   r`   ri   )
r3   rf   r_   r   r   r   rK   sfrp   r   s
             r   gf_frobenius_mapr     s    2 	!A|q1aA	!A
B%B1a!e_ !!A$!a%!Q/B1a ! Ir!   c                     t        | |||      } | }| }t        d|      D ]-  }t        |||||      }t        ||||      }t        ||||      }/ t	        ||dz
  dz  |||      }	|	S )z
    utility function for ``gf_edf_zassenhaus``
    Compute ``f**((p**n - 1) // 2)`` in ``GF(p)[x]/(g)``
    ``f**((p**n - 1) // 2) = (f*f**p*...*f**(p**n - 1))**((p - 1) // 2)``
    r0   r+   )r   rI   r   rr   r   )
r3   rK   rf   r_   r   r   rL   r   rp   ress
             r   _gf_pow_pnm1d2r     s     	q!QA	A	A1a[ Q1a+1aA1aA
 QQ
Aq!
,CJr!   c                 6   |s|j                   gS |dk(  rt        | |||      S |dk(  rt        t        | ||      |||      S |j                   g}	 |dz  r!t        || ||      }t        ||||      }|dz  }|dz  }|s	 |S t        | ||      } t        | |||      } L)a*  
    Compute ``f**n`` in ``GF(p)[x]/(g)`` using repeated squaring.

    Given polynomials ``f`` and ``g`` in ``GF(p)[x]`` and a non-negative
    integer ``n``, efficiently computes ``f**n (mod g)`` i.e. the remainder
    of ``f**n`` from division by ``g``, using the repeated squaring algorithm.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_pow_mod

    >>> gf_pow_mod(ZZ.map([3, 2, 4]), 3, ZZ.map([1, 1]), 5, ZZ)
    []

    References
    ==========

    .. [1] [Gathen99]_

    r0   r+   )r   r   rw   rr   )r3   rK   rf   r   r   rL   s         r   r   r     s    . w	
aaAq!!	
afQ1oq!Q//	
A
q5q!Q"Aq!Q"AFA	a
 H 1aO1aA r!   c                 L    |r|t        | |||      }} |rt        | ||      d   S )z
    Euclidean Algorithm in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_gcd

    >>> gf_gcd(ZZ.map([3, 2, 4]), ZZ.map([2, 2, 3]), 5, ZZ)
    [1, 3]

    r0   )r   gf_monicr   s       r   gf_gcdr     s6     &Aq!$1  Aq!Qr!   c           	      z    | r|sg S t        t        | |||      t        | |||      ||      }t        |||      d   S )z
    Compute polynomial LCM in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_lcm

    >>> gf_lcm(ZZ.map([3, 2, 4]), ZZ.map([2, 2, 3]), 5, ZZ)
    [1, 2, 0, 4]

    r0   )r   rr   r   r   r3   rf   r   r   rL   s        r   gf_lcmr   %  sM     A	vaAq!aAq!1a	)A Aq!Qr!   c                 j    | s|sg g g fS t        | |||      }|t        | |||      t        ||||      fS )a   
    Compute polynomial GCD and cofactors in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_cofactors

    >>> gf_cofactors(ZZ.map([3, 2, 4]), ZZ.map([2, 2, 3]), 5, ZZ)
    ([1, 3], [3, 3], [2, 1])

    )r   r   r   s        r   gf_cofactorsr   <  sM     QB|q!QAvaAq!1aA   r!   c                    | s|s|j                   gg g fS t        | ||      \  }}t        |||      \  }}| sg |j                  ||      g|fS |s|j                  ||      gg |fS |j                  ||      gg }	}g |j                  ||      g}}
	 t        ||||      \  }}|sndt        |||      |c\  }}}|j                  ||      }t	        ||	|||      }t	        |
||||      }t        ||||      |	}}	t        ||||      |}
}x|	||fS )a  
    Extended Euclidean Algorithm in ``GF(p)[x]``.

    Given polynomials ``f`` and ``g`` in ``GF(p)[x]``, computes polynomials
    ``s``, ``t`` and ``h``, such that ``h = gcd(f, g)`` and ``s*f + t*g = h``.
    The typical application of EEA is solving polynomial diophantine equations.

    Consider polynomials ``f = (x + 7) (x + 1)``, ``g = (x + 7) (x**2 + 1)``
    in ``GF(11)[x]``. Application of Extended Euclidean Algorithm gives::

       >>> from sympy.polys.domains import ZZ
       >>> from sympy.polys.galoistools import gf_gcdex, gf_mul, gf_add

       >>> s, t, g = gf_gcdex(ZZ.map([1, 8, 7]), ZZ.map([1, 7, 1, 7]), 11, ZZ)
       >>> s, t, g
       ([5, 6], [6], [1, 7])

    As result we obtained polynomials ``s = 5*x + 6`` and ``t = 6``, and
    additionally ``gcd(f, g) = x + 7``. This is correct because::

       >>> S = gf_mul(s, ZZ.map([1, 8, 7]), 11, ZZ)
       >>> T = gf_mul(t, ZZ.map([1, 7, 1, 7]), 11, ZZ)

       >>> gf_add(S, T, 11, ZZ) == [1, 7]
       True

    References
    ==========

    .. [1] [Gathen99]_

    )r   r   r
   r   r|   r`   )r3   rf   r   r   p0r0p1r1s0s1t0t1QRr   r   r   ts                     r   gf_gcdexr   S  sI   B wBaAFBaAFBAHHRO$b((Q "b((hhr1oB!((2q/"B
b"a#11a("R"hhr1or2q!Q'r2q!Q'q#q!,bBq#q!,bB   r2:r!   c                     | s|j                   g fS | d   }|j                  |      r|t        |       fS |t        | |||      fS )z
    Compute LC and a monic polynomial in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_monic

    >>> gf_monic(ZZ.map([3, 2, 4]), 5, ZZ)
    (3, [1, 4, 3])

    r   )r   is_onerB   rb   )r3   r   r   r   s       r   r   r     sM     vvrzqT88B<tAw;}QAq111r!   c                     t        |       }|j                  g|z  |}}| dd D ]!  }| ||      z  }||z  }|r||||z
  <   |dz  }# t        |      S )z
    Differentiate polynomial in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_diff

    >>> gf_diff([3, 2, 4], 5, ZZ)
    [1, 2]

    Nr#   r0   )r4   r   r>   )r3   r   r   rg   rL   rK   r=   s          r   gf_diffr     sp     
1BFF8B;qA3B 1
Ab1fI	Q A;r!   c                 J    |j                   }| D ]  }||z  }||z  }||z  } |S )z
    Evaluate ``f(a)`` in ``GF(p)`` using Horner scheme.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_eval

    >>> gf_eval([3, 2, 4], 2, 5, ZZ)
    0

    r6   )r3   r-   r   r   rP   rU   s         r   gf_evalr     s>     VVF !!!
 Mr!   c           	      D    |D cg c]  }t        | |||       c}S c c}w )a  
    Evaluate ``f(a)`` for ``a`` in ``[a_1, ..., a_n]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_multi_eval

    >>> gf_multi_eval([3, 2, 4], [0, 1, 2, 3, 4], 5, ZZ)
    [4, 4, 0, 2, 0]

    )r   )r3   Ar   r   r-   s        r   gf_multi_evalr     s#     +,-QWQ1a ---s   c           	          t        |      dk  r"t        t        | t        ||      ||      g      S | sg S | d   g}| dd D ]  }t	        ||||      }t        ||||      }  |S )a  
    Compute polynomial composition ``f(g)`` in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_compose

    >>> gf_compose([3, 2, 4], [2, 2, 2], 5, ZZ)
    [2, 4, 0, 3, 0]

    r0   r   N)r2   r>   r   r8   rr   r[   )r3   rf   r   r   rL   rU   s         r   
gf_composer     s}     1v{E!QKA6788		
1AqrU &1aA!Q1%& Hr!   c                     | sg S | d   g}| dd D ],  }t        ||||      }t        ||||      }t        ||||      }. |S )a&  
    Compute polynomial composition ``g(h)`` in ``GF(p)[x]/(f)``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_compose_mod

    >>> gf_compose_mod(ZZ.map([3, 2, 4]), ZZ.map([2, 2, 2]), ZZ.map([4, 3]), 5, ZZ)
    [4]

    r   r0   N)rr   r[   r   )rf   rL   r3   r   r   compr-   s          r   gf_compose_modr     sc     	aD6DqrU %dAq!$T1a+dAq!$%
 Kr!   c           
      J   t        | ||||      }|}|dz  rt        | |||      }	|}
n| }	|}
|dz  }|rat        |t        |||||      ||      }t        |||||      }|dz  r*t        |	t        ||
|||      ||      }	t        ||
|||      }
|dz  }|rat        | |
|||      |	fS )a  
    Compute polynomial trace map in ``GF(p)[x]/(f)``.

    Given a polynomial ``f`` in ``GF(p)[x]``, polynomials ``a``, ``b``,
    ``c`` in the quotient ring ``GF(p)[x]/(f)`` such that ``b = c**t
    (mod f)`` for some positive power ``t`` of ``p``, and a positive
    integer ``n``, returns a mapping::

       a -> a**t**n, a + a**t + a**t**2 + ... + a**t**n (mod f)

    In factorization context, ``b = x**p mod f`` and ``c = x mod f``.
    This way we can efficiently compute trace polynomials in equal
    degree factorization routine, much faster than with other methods,
    like iterated Frobenius algorithm, for large degrees.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_trace_map

    >>> gf_trace_map([1, 2], [4, 4], [1, 1], 4, [3, 2, 4], 5, ZZ)
    ([1, 3], [1, 3])

    References
    ==========

    .. [1] [Gathen92]_

    r0   )r   ri   )r-   r_   rU   rK   r3   r   r   r   r   r   Vs              r   gf_trace_mapr   -  s    > 	q!Q1%A	A1u1aA!GA
1nQ1a3Q:1aAq)q5q.Aq!Q7A>Aq!Q1-A	a  !Q1a(!++r!   c                     t        | |||      } | }| }t        d|      D ]-  }t        |||||      }t        ||||      }t        ||||      }/ |S )z&
    utility for ``gf_edf_shoup``
    r0   )r   rI   r   ri   )	r3   rK   rf   r_   r   r   rL   r   rp   s	            r   _gf_trace_mapr   d  sl     	q!QA	A	A1a[ Q1a+1aA1aA Hr!   c                     t        |      }|j                  gt        d|       D cg c]  } |t        t        d|                   c}z   S c c}w )a  
    Generate a random polynomial in ``GF(p)[x]`` of degree ``n``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_random
    >>> gf_random(10, 5, ZZ) #doctest: +SKIP
    [1, 2, 3, 2, 1, 1, 1, 2, 0, 4, 2]

    r   )intr   rI   r   )rK   r   r   pirp   s        r   	gf_randomr   r  sB     
QBEE7uQ{D!qWQ^,-DDDDs   "Ac                 >    	 t        | ||      }t        |||      r|S )a,  
    Generate random irreducible polynomial of degree ``n`` in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_irreducible
    >>> gf_irreducible(10, 5, ZZ) #doctest: +SKIP
    [1, 4, 2, 2, 3, 2, 4, 1, 4, 0, 4]

    )r   gf_irreducible_p)rK   r   r   r3   s       r   gf_irreducibler     s+     aAAq!$H r!   c                    t        |       }|dk  ryt        | ||      \  }} |dk  rt        |j                  |j                  g|| ||      x}}t        d|dz        D ]S  }t        ||j                  |j                  g||      }t        | |||      |j                  gk(  rt        ||| ||      }S y yt        | ||      }	t        |j                  |j                  g| |	||      x}}t        d|dz        D ]S  }t        ||j                  |j                  g||      }t        | |||      |j                  gk(  rt        || |	||      }S y y)a_  
    Ben-Or's polynomial irreducibility test over finite fields.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_irred_p_ben_or

    >>> gf_irred_p_ben_or(ZZ.map([1, 4, 2, 2, 3, 2, 4, 1, 4, 0, 4]), 5, ZZ)
    True
    >>> gf_irred_p_ben_or(ZZ.map([3, 2, 4]), 5, ZZ)
    False

    r0   T   r   r+   F)r4   r   r   r   r   rI   rk   r   r   r   r   )
r3   r   r   rK   r   HrL   rp   rf   r_   s
             r   gf_irred_p_ben_orr     sV     	!AAvAq!DAq1uAEE166?Aq!Q77Aq!Q$ 	Aq155!&&/1a0AaAq!aeeW,"1aAq1	"  'q!Q/ !%%!Q1==Aq!Q$ 	Aq155!&&/1a0AaAq!aeeW,$Q1a3	 r!   c                    t        |       }|dk  ryt        | ||      \  }} |j                  |j                  g}ddlm}  ||      D ch c]  }||z  	 }}t        | ||      }	|	d   }
t        d|      D ]A  }||v r,t        |
|||      }t        | |||      |j                  gk7  r yt        |
| |	||      }
C |
|k(  S c c}w )a[  
    Rabin's polynomial irreducibility test over finite fields.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_irred_p_rabin

    >>> gf_irred_p_rabin(ZZ.map([1, 4, 2, 2, 3, 2, 4, 1, 4, 0, 4]), 5, ZZ)
    True
    >>> gf_irred_p_rabin(ZZ.map([3, 2, 4]), 5, ZZ)
    False

    r0   Tr   	factorintF)r4   r   r   r   sympy.ntheoryr   r   rI   rk   r   r   )r3   r   r   rK   r   xr   dindicesr_   rL   rp   rf   s                r   gf_irred_p_rabinr     s      	!AAvAq!DAq	
A''l,1,G,"1a+A	!A1a[ ,<q!Q"AaAq!aeeW,Q1a+, 6M -s   
B?)zben-orrabinc                 ^    t        d      }|t        |   | ||      }|S t        | ||      }|S )a[  
    Test irreducibility of a polynomial ``f`` in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_irreducible_p

    >>> gf_irreducible_p(ZZ.map([1, 4, 2, 2, 3, 2, 4, 1, 4, 0, 4]), 5, ZZ)
    True
    >>> gf_irreducible_p(ZZ.map([3, 2, 4]), 5, ZZ)
    False

    GF_IRRED_METHOD)r   _irred_methodsr   )r3   r   r   methodirreds        r   r   r     sD      $%Fv&q!Q/ L !Aq)Lr!   c                 v    t        | ||      \  }} | syt        | t        | ||      ||      |j                  gk(  S )a5  
    Return ``True`` if ``f`` is square-free in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_sqf_p

    >>> gf_sqf_p(ZZ.map([3, 2, 4]), 5, ZZ)
    True
    >>> gf_sqf_p(ZZ.map([2, 4, 4, 2, 2, 1, 4]), 5, ZZ)
    False

    T)r   r   r   r   )r3   r   r   r   s       r   gf_sqf_pr     sA      Aq!DAqaAq)1a0QUUG;;r!   c                 p    t        | ||      \  }}|j                  g}|D ]  \  } }t        || ||      } |S )a  
    Return square-free part of a ``GF(p)[x]`` polynomial.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_sqf_part

    >>> gf_sqf_part(ZZ.map([1, 1, 3, 0, 1, 0, 2, 2, 1]), 5, ZZ)
    [1, 4, 3]

    )gf_sqf_listr   rr   )r3   r   r   r   sqfrf   s         r   gf_sqf_partr   &  sK     Aq!FAs	
A 11aA Hr!   c                    ddg t        |      f\  }}}}t        | ||      \  }} t        |       dk  r|g fS 	 t        | ||      }	|	g k7  rt	        | |	||      }
t        | |
||      }d}||j                  gk7  rft	        |
|||      }t        ||||      }t        |      dkD  r|j                  |||z  f       t        |
|||      ||dz   }}}
||j                  gk7  rf|
|j                  gk(  rd}n|
} |s;t        |       |z  }t        d|dz         D ]  }| ||z     | |<    | d|dz    ||z  }} nn|rt        d      ||fS )a  
    Return the square-free decomposition of a ``GF(p)[x]`` polynomial.

    Given a polynomial ``f`` in ``GF(p)[x]``, returns the leading coefficient
    of ``f`` and a square-free decomposition ``f_1**e_1 f_2**e_2 ... f_k**e_k``
    such that all ``f_i`` are monic polynomials and ``(f_i, f_j)`` for ``i != j``
    are co-prime and ``e_1 ... e_k`` are given in increasing order. All trivial
    terms (i.e. ``f_i = 1``) are not included in the output.

    Consider polynomial ``f = x**11 + 1`` over ``GF(11)[x]``::

       >>> from sympy.polys.domains import ZZ

       >>> from sympy.polys.galoistools import (
       ...     gf_from_dict, gf_diff, gf_sqf_list, gf_pow,
       ... )
       ... # doctest: +NORMALIZE_WHITESPACE

       >>> f = gf_from_dict({11: ZZ(1), 0: ZZ(1)}, 11, ZZ)

    Note that ``f'(x) = 0``::

       >>> gf_diff(f, 11, ZZ)
       []

    This phenomenon does not happen in characteristic zero. However we can
    still compute square-free decomposition of ``f`` using ``gf_sqf()``::

       >>> gf_sqf_list(f, 11, ZZ)
       (1, [([1, 1], 11)])

    We obtained factorization ``f = (x + 1)**11``. This is correct because::

       >>> gf_pow([1, 1], 11, 11, ZZ) == f
       True

    References
    ==========

    .. [1] [Geddes92]_

    r0   FTr   Nz'all=True' is not supported yet)
r   r   r4   r   r   r   r   r$   rI   
ValueError)r3   r   r   allrK   r   factorsr   r   r   rf   rL   rp   Gr   r   s                   r   r   r   >  s   V E2s1v-AsGQQ1EB|a2v
Aq!7q!Q"Aq!Q"AAw,1aA&1aA&Q<!#NNAqs8, Aq!,aQa1 w, QUUG|!!A1a!e_ 1v! Va!e9acqA? B :;;w;r!   c           	         t        |       t        |      }}|j                  g|j                  g|dz
  z  z   }t	        |      gg g|dz
  z  z   }t        d|dz
  |z  dz         D ]g  }|d    | d   z  |z  g|d   }	}t        d|      D ])  }
|j                  ||
dz
     |	| |
 dz
     z  z
  |z         + ||z  st	        |      |||z  <   |}i |S )ad  
    Calculate Berlekamp's ``Q`` matrix.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_Qmatrix

    >>> gf_Qmatrix([3, 2, 4], 5, ZZ)
    [[1, 0],
     [3, 4]]

    >>> gf_Qmatrix([1, 0, 0, 0, 1], 5, ZZ)
    [[1, 0, 0, 0],
     [0, 4, 0, 0],
     [0, 0, 1, 0],
     [0, 0, 0, 4]]

    r0   r#   )r4   r   r   r   rB   rI   r$   )r3   r   r   rK   r   r   r   rp   qqrU   rq   s              r   
gf_Qmatrixr     s    * Q<QqA	
166(AE""A	a	RD!a%L A1q1uai!m$ 	R5&2,!#$aeAq! 	4AIIqQx!Aqb1fI+-23	4 A2hAadG	 Hr!   c                 ~   | D cg c]  }t        |       c}t        |       }} t        d|      D ]   }| |   |   |j                  z
  |z  | |   |<   " t        d|      D ]  }t        ||      D ]  }| |   |   s n |j	                  | |   |   |      }t        d|      D ]  }| |   |   |z  |z  | |   |<    t        d|      D ]   }| |   |   }	| |   |   | |   |<   |	| |   |<   " t        d|      D ]>  }||k7  s	| |   |   }t        d|      D ]  }| |   |   | |   |   |z  z
  |z  | |   |<   ! @  t        d|      D ]I  }t        d|      D ]8  }||k(  r|j                  | |   |   z
  |z  | |   |<   '| |   |    |z  | |   |<   : K g }
| D ]  }t        |      s|
j                  |       ! |
S c c}w )a_  
    Compute a basis of the kernel of ``Q``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_Qmatrix, gf_Qbasis

    >>> gf_Qbasis(gf_Qmatrix([1, 0, 0, 0, 1], 5, ZZ), 5, ZZ)
    [[1, 0, 0, 0], [0, 0, 1, 0]]

    >>> gf_Qbasis(gf_Qmatrix([3, 2, 4], 5, ZZ), 5, ZZ)
    [[1, 0]]

    r   )rB   r2   rI   r   r
   anyr$   )r   r   r   r   rK   r<   rp   r   rq   r   basiss              r   	gf_Qbasisr     s7   "  !T!W!3q6qA1a[ (Q47QUU?a'!Q( 1a[ 8q! 	AtAw	 hhqtAw"q! 	(AtAws{a'AaDG	( q! 	A!QAd1gAaDGAaDG	
 q! 	8AAvaDGq! 8A tAw1a2a7AaDG8		8#80 1a[ )q! 	)AAv551Q47?a/!QaDG8q.!Q		)) E q6LLO LU "s   F:c                 z   t        | ||      }t        |||      }t        |      D ]%  \  }}t        t	        t        |                  ||<   ' | g}t        dt        |            D ]  }t	        |      D ]  } |j                  }	|	|k  st        ||   |	||      }
t        | |
||      }||j                  gk7  r7|| k7  r2|j                  |        t        | |||      } |j                  | |g       t        |      t        |      k(  rt        |d      c c S |	|j                  z  }	|	|k  r  t        |d      S )a  
    Factor a square-free ``f`` in ``GF(p)[x]`` for small ``p``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_berlekamp

    >>> gf_berlekamp([1, 0, 0, 0, 1], 5, ZZ)
    [[1, 0, 2], [1, 0, 3]]

    r0   Fmultiple)r   r   	enumerater>   rB   reversedrI   r2   r   r]   r   r   remover   extendr   )r3   r   r   r   r   rp   r   r   r<   r   rf   rL   s               r   gf_berlekampr     s9    	1aA!QA! +1Xa[)*!+ cG1c!f g 	AAa%!!A$1a01aA&<AFNN1%q!Q*ANNAq6*w<3q6)(5AAQUU
 a%	& 511r!   c           	          d|j                   |j                  gg }}}t        | ||      }d|z  t        |       k  rt	        || |||      }t        | t        ||j                   |j                  g||      ||      }||j                   gk7  r<|j                  ||f       t        | |||      } t        || ||      }t        | ||      }|dz  }d|z  t        |       k  r| |j                   gk7  r|| t        |       fgz   S |S )a{  
    Cantor-Zassenhaus: Deterministic Distinct Degree Factorization

    Given a monic square-free polynomial ``f`` in ``GF(p)[x]``, computes
    partial distinct degree factorization ``f_1 ... f_d`` of ``f`` where
    ``deg(f_i) != deg(f_j)`` for ``i != j``. The result is returned as a
    list of pairs ``(f_i, e_i)`` where ``deg(f_i) > 0`` and ``e_i > 0``
    is an argument to the equal degree factorization routine.

    Consider the polynomial ``x**15 - 1`` in ``GF(11)[x]``::

       >>> from sympy.polys.domains import ZZ
       >>> from sympy.polys.galoistools import gf_from_dict

       >>> f = gf_from_dict({15: ZZ(1), 0: ZZ(-1)}, 11, ZZ)

    Distinct degree factorization gives::

       >>> from sympy.polys.galoistools import gf_ddf_zassenhaus

       >>> gf_ddf_zassenhaus(f, 11, ZZ)
       [([1, 0, 0, 0, 0, 10], 1), ([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2)]

    which means ``x**15 - 1 = (x**5 - 1) (x**10 + x**5 + 1)``. To obtain
    factorization into irreducibles, use equal degree factorization
    procedure (EDF) with each of the factors.

    References
    ==========

    .. [1] [Gathen99]_
    .. [2] [Geddes92]_

    r0   r+   )
r   r   r   r4   r   r   rk   r$   r   r   )r3   r   r   rp   rf   r   r_   rL   s           r   gf_ddf_zassenhausr  )  s   F qvv'qA"1a+A
A#1
Q1a+1fQA61=<NNAq6"q!Q"Aq!Q"A*1a3A	Q A#1
 	QUUG|1il+,,,r!   c           	         | g}t        |       |k  r|S t        |       |z  }|dk7  rt        | ||      }|j                  |j                  g}t	        |      |k  r|dk(  r^|x}}	t        |dz
        D ]  }
t        |	d| ||      }	t        ||	||      }! t        | |||      }||j                  |j                  gz  }nGt        d|z  dz
  ||      }	t        |	|| ||      }t        | t        ||j                  ||      ||      }||j                  gk7  r.|| k7  r)t        ||||      t        t        | |||      |||      z   }t	        |      |k  rt        |d      S )a  
    Cantor-Zassenhaus: Probabilistic Equal Degree Factorization

    Given a monic square-free polynomial ``f`` in ``GF(p)[x]`` and
    an integer ``n``, such that ``n`` divides ``deg(f)``, returns all
    irreducible factors ``f_1,...,f_d`` of ``f``, each of degree ``n``.
    EDF procedure gives complete factorization over Galois fields.

    Consider the square-free polynomial ``f = x**3 + x**2 + x + 1`` in
    ``GF(5)[x]``. Let's compute its irreducible factors of degree one::

       >>> from sympy.polys.domains import ZZ
       >>> from sympy.polys.galoistools import gf_edf_zassenhaus

       >>> gf_edf_zassenhaus([1,1,1,1], 1, 5, ZZ)
       [[1, 1], [1, 2], [1, 3]]

    Notes
    =====

    The case p == 2 is handled by Cohen's Algorithm 3.4.8. The case p odd is
    as in Geddes Algorithm 8.9 (or Cohen's Algorithm 3.4.6).

    References
    ==========

    .. [1] [Gathen99]_
    .. [2] [Geddes92]_ Algorithm 8.9
    .. [3] [Cohen93]_ Algorithm 3.4.8

    r+   r0   Fr   )r4   r   r   r   r2   rI   r   ri   r   r   r   r]   gf_edf_zassenhausr   r   )r3   rK   r   r   r   Nr_   r   rL   r   rp   rf   s               r   r  r  b  sw   @ cG|q!AAv&q!Q/	
A
g,
6IA1q5\ 'q!Q1-1aA&' q!Q"A!&&!&&!!A!a%!)Q*Aq!Q1a0Aq-155!Q7A>A<AF'1a3#F1aA$61a@AG! g,
& 511r!   c                    t        |       }t        t        t        |dz                    }t	        | ||      }t        |j                  |j                  g| |||      }|j                  |j                  g|g|j                  g|dz
  z  z   }t        d|dz         D ]  }t        ||dz
     | |||      ||<    ||   |d| }}|g|j                  g|dz
  z  z   }	t        d|      D ]  }t        |	|dz
     || ||      |	|<    g }
t        |	      D ]  \  }}|j                  g|dz
  }}|D ],  }t        ||||      }t        ||||      }t        || ||      }. t        | |||      }t        | |||      } t!        |      D ]]  }t        ||||      }t        ||||      }||j                  gk7  r|
j#                  |||dz   z  |z
  f       t        ||||      |dz
  }}_  | |j                  gk7  r|
j#                  | t        |       f       |
S )a  
    Kaltofen-Shoup: Deterministic Distinct Degree Factorization

    Given a monic square-free polynomial ``f`` in ``GF(p)[x]``, computes
    partial distinct degree factorization ``f_1,...,f_d`` of ``f`` where
    ``deg(f_i) != deg(f_j)`` for ``i != j``. The result is returned as a
    list of pairs ``(f_i, e_i)`` where ``deg(f_i) > 0`` and ``e_i > 0``
    is an argument to the equal degree factorization routine.

    This algorithm is an improved version of Zassenhaus algorithm for
    large ``deg(f)`` and modulus ``p`` (especially for ``deg(f) ~ lg(p)``).

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_ddf_shoup, gf_from_dict

    >>> f = gf_from_dict({6: ZZ(1), 5: ZZ(-1), 4: ZZ(1), 3: ZZ(1), 1: ZZ(-1)}, 3, ZZ)

    >>> gf_ddf_shoup(f, 3, ZZ)
    [([1, 1, 0], 1), ([1, 1, 0, 1, 2], 2)]

    References
    ==========

    .. [1] [Kaltofen98]_
    .. [2] [Shoup95]_
    .. [3] [Gathen92]_

    r+   r0   N)r4   r   _ceil_sqrtr   r   r   r   rI   r   r   rk   rr   r   r   r   r   r$   )r3   r   r   rK   r<   r_   rL   r   rp   r   r   r   rq   r   rf   r   s                   r   gf_ddf_shoupr    sE   @ 	!AE%1+A"1a+A!%%!Q15A
%%!xQ//A1a!e_ 4!A#1a3!4 Q42AqA	
qvvhAA1a[ 4aAh1a3!4 G! -1wA1 	#Aq!Q"Aq!Q"Aq!Q"A	#
 1aA1aA! 	-Aq!Q"Aq!Q"AQUUG|1a!e9q=12!Q1%q1uqA	--( 	QUUG|9Q<()Nr!   c           	         t        |       t        |      }}|sg S ||k  r| gS | g|j                  |j                  g}}t	        |dz
  ||      }|dk(  r`t        ||| ||      }	t        ||	||dz
  | ||      d   }
t        | |
||      }t        | |||      }t        ||||      t        ||||      z   }nt        | ||      }t        ||| |||      }
t        |
|dz
  dz  | ||      }	t        | |	||      }t        | t        |	|j                  ||      ||      }t        | t        ||||      ||      }t        ||||      t        ||||      z   t        ||||      z   }t        |d      S )a  
    Gathen-Shoup: Probabilistic Equal Degree Factorization

    Given a monic square-free polynomial ``f`` in ``GF(p)[x]`` and integer
    ``n`` such that ``n`` divides ``deg(f)``, returns all irreducible factors
    ``f_1,...,f_d`` of ``f``, each of degree ``n``. This is a complete
    factorization over Galois fields.

    This algorithm is an improved version of Zassenhaus algorithm for
    large ``deg(f)`` and modulus ``p`` (especially for ``deg(f) ~ lg(p)``).

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_edf_shoup

    >>> gf_edf_shoup(ZZ.map([1, 2837, 2277]), 1, 2917, ZZ)
    [[1, 852], [1, 1985]]

    References
    ==========

    .. [1] [Shoup91]_
    .. [2] [Gathen92]_

    r0   r+   Fr   )r4   r   r   r   r   r   r   r   r   gf_edf_shoupr   r   r]   rr   r   )r3   rK   r   r   r  r   r   r   r   rL   r   h1h2r_   h3s                  r   r
  r
    s   8 Q<QqA	Avs
quuaffoQG!a%AAAvq!Q1%Aq!a%Aq1!4Aq!QAr1a r1a+2q!Q'( 'q!Q/!Q1a+q1q51*aA.Aq!QA}Qq!4a;Avb"a+Q2r1a+2q!Q'(2q!Q'( 511r!   c                 l    g }t        | ||      D ]  \  }}|t        ||||      z  } t        |d      S )a  
    Factor a square-free ``f`` in ``GF(p)[x]`` for medium ``p``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_zassenhaus

    >>> gf_zassenhaus(ZZ.map([1, 4, 3]), 5, ZZ)
    [[1, 1], [1, 3]]

    Fr   )r  r  r   r3   r   r   r   factorrK   s         r   gf_zassenhausr  -  sJ     G&q!Q/ 6	$VQ1556 511r!   c                 l    g }t        | ||      D ]  \  }}|t        ||||      z  } t        |d      S )a  
    Factor a square-free ``f`` in ``GF(p)[x]`` for large ``p``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_shoup

    >>> gf_shoup(ZZ.map([1, 4, 3]), 5, ZZ)
    [[1, 1], [1, 3]]

    Fr   )r  r
  r   r  s         r   gf_shoupr  C  sI     G!!Q* 1	<1a001 511r!   )	berlekamp
zassenhausshoupc                     t        | ||      \  }} t        |       dk  r|g fS |xs t        d      }|t        |   | ||      }||fS t	        | ||      }||fS )a  
    Factor a square-free polynomial ``f`` in ``GF(p)[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.galoistools import gf_factor_sqf

    >>> gf_factor_sqf(ZZ.map([3, 2, 4]), 5, ZZ)
    (3, [[1, 1], [1, 3]])

    r0   GF_FACTOR_METHOD)r   r4   r   _factor_methodsr  )r3   r   r   r   r   r   s         r   gf_factor_sqfr  _  sz     Q1EB|a2v0u/0F!&)!Q2 w;  1a(w;r!   c                     t        | ||      \  }} t        |       dk  r|g fS g }t        | ||      d   D ]-  \  }}t        |||      d   D ]  }|j	                  ||f        / |t        |      fS )a  
    Factor (non square-free) polynomials in ``GF(p)[x]``.

    Given a possibly non square-free polynomial ``f`` in ``GF(p)[x]``,
    returns its complete factorization into irreducibles::

                 f_1(x)**e_1 f_2(x)**e_2 ... f_d(x)**e_d

    where each ``f_i`` is a monic polynomial and ``gcd(f_i, f_j) == 1``,
    for ``i != j``.  The result is given as a tuple consisting of the
    leading coefficient of ``f`` and a list of factors of ``f`` with
    their multiplicities.

    The algorithm proceeds by first computing square-free decomposition
    of ``f`` and then iteratively factoring each of square-free factors.

    Consider a non square-free polynomial ``f = (7*x + 1) (x + 2)**2`` in
    ``GF(11)[x]``. We obtain its factorization into irreducibles as follows::

       >>> from sympy.polys.domains import ZZ
       >>> from sympy.polys.galoistools import gf_factor

       >>> gf_factor(ZZ.map([5, 2, 7, 2]), 11, ZZ)
       (5, [([1, 2], 1), ([1, 8], 2)])

    We arrived with factorization ``f = 5 (x + 2) (x + 8)**2``. We did not
    recover the exact form of the input polynomial because we requested to
    get monic factors of ``f`` and its leading coefficient separately.

    Square-free factors of ``f`` can be factored into irreducibles over
    ``GF(p)`` using three very different methods:

    Berlekamp
        efficient for very small values of ``p`` (usually ``p < 25``)
    Cantor-Zassenhaus
        efficient on average input and with "typical" ``p``
    Shoup-Kaltofen-Gathen
        efficient with very large inputs and modulus

    If you want to use a specific factorization method, instead of the default
    one, set ``GF_FACTOR_METHOD`` with one of ``berlekamp``, ``zassenhaus`` or
    ``shoup`` values.

    References
    ==========

    .. [1] [Gathen99]_

    r0   )r   r4   r   r  r$   r   )r3   r   r   r   r   rf   rK   rL   s           r   	gf_factorr  |  s    d Q1EB|a2vGAq!$Q' #1q!Q'* 	#ANNAq6"	## }W%%%r!   c                 ,    d}| D ]  }||z  }||z  } |S )z
    Value of polynomial 'f' at 'a' in field R.

    Examples
    ========

    >>> from sympy.polys.galoistools import gf_value

    >>> gf_value([1, 7, 2, 4], 11)
    2204

    r   r,   )r3   r-   rP   rU   s       r   gf_valuer    s1     F !! Mr!   c                     ddl m} | |z  dk(  r||z  dk(  rt        t        |            S g S  || |      \  }}}||z  dk7  rg S t        |      D cg c]  }||z  |z  ||z  |z  z   |z   c}S c c}w )a  
    Returns the values of x satisfying a*x congruent b mod(m)

    Here m is positive integer and a, b are natural numbers.
    This function returns only those values of x which are distinct mod(m).

    Examples
    ========

    >>> from sympy.polys.galoistools import linear_congruence

    >>> linear_congruence(3, 12, 15)
    [4, 9, 14]

    There are 3 solutions distinct mod(15) since gcd(a, m) = gcd(3, 15) = 3.

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Linear_congruence_theorem

    r   )r   )sympy.polys.polytoolsr   rB   rI   )r-   r_   r   r   r   r   rf   r   s           r   linear_congruencer!    s    . ,1uzq5A:a>!IAqkGAq!1uz	388<aQUaZ!a%1*$)<<<s   A/c                     ddl m} t        |||      }t        ||       }t        ||        ||z  z  }t	        |||      S )a0  
    Used in gf_csolve to generate solutions of f(x) cong 0 mod(p**(s + 1))
    from the solutions of f(x) cong 0 mod(p**s).

    Examples
    ========

    >>> from sympy.polys.galoistools import _raise_mod_power
    >>> from sympy.polys.galoistools import csolve_prime

    These is the solutions of f(x) = x**2 + x + 7 cong 0 mod(3)

    >>> f = [1, 1, 7]
    >>> csolve_prime(f, 3)
    [1]
    >>> [ i for i in range(3) if not (i**2 + i + 7) % 3]
    [1]

    The solutions of f(x) cong 0 mod(9) are constructed from the
    values returned from _raise_mod_power:

    >>> x, s, p = 1, 1, 3
    >>> V = _raise_mod_power(x, s, p, f)
    >>> [x + v * p**s for v in V]
    [1, 4, 7]

    And these are confirmed with the following:

    >>> [ i for i in range(3**2) if not (i**2 + i + 7) % 3**2]
    [1, 4, 7]

    r   ZZ)sympy.polys.domainsr$  r   r  r!  )r   r   r   r3   r$  f_falphabetas           r   _raise_mod_powerr)    sH    B '
!Q
CS!Ea^q!t#DUD!,,r!   c                 n   ddl m} ddlm} t	        |      }t               }t        ddgdz
  | |      }t        |d|      }t        | ||      g}|rT|j                         } t        |       dk  r"t        |       dk(  r)|j                  t        | d          | d   z  z         Yt        |       dk(  rYt        | d         }	| d   |	z  z  dz  z  z   dz  |j                  fd |dz  | d   |	z  z
  d	      D               	  |ddz
        }
t        d|
gdz
  dz  | |      }t        |d|      }t        | ||      }dt        |      cxk  rt        |       k  r5n n2|j                  |       |j                  t        | ||      d          n|rTt!        |      S )
a*   Solutions of `f(x) \equiv 0 \pmod{p}`, `f(0) \not\equiv 0 \pmod{p}`.

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

    This algorithm is classified as the Las Vegas method.
    That is, it always returns the correct answer and solves the problem
    fast in many cases, but if it is unlucky, it does not answer forever.

    Suppose the polynomial f is not a zero polynomial. Assume further
    that it is of degree at most p-1 and `f(0)\not\equiv 0 \pmod{p}`.
    These assumptions are not an essential part of the algorithm,
    only that it is more convenient for the function calling this
    function to resolve them.

    Note that `x^{p-1} - 1 \equiv \prod_{a=1}^{p-1}(x - a) \pmod{p}`.
    Thus, the greatest common divisor with f is `\prod_{s \in S}(x - s)`,
    with S being the set of solutions to f. Furthermore,
    when a is randomly determined, `(x+a)^{(p-1)/2}-1` is
    a polynomial with (p-1)/2 randomly chosen solutions.
    The greatest common divisor of f may be a nontrivial factor of f.

    When p is large and the degree of f is small,
    it is faster than naive solution methods.

    Parameters
    ==========

    f : polynomial
    p : prime number

    Returns
    =======

    list[int]
        a list of solutions, sorted in ascending order
        by integers in the range [1, p). The same value
        does not exist in the list even if there is
        a multiple solution. If no solution exists, returns [].

    Examples
    ========

    >>> from sympy.polys.galoistools import _csolve_prime_las_vegas
    >>> _csolve_prime_las_vegas([1, 4, 3], 7) # x^2 + 4x + 3 = 0 (mod 7)
    [4, 6]
    >>> _csolve_prime_las_vegas([5, 7, 1, 9], 11) # 5x^3 + 7x^2 + x + 9 = 0 (mod 11)
    [1, 5, 8]

    References
    ==========

    .. [1] R. Crandall and C. Pomerance "Prime Numbers", 2nd Ed., Algorithm 2.3.10

    r   r#  )sqrt_modr0   r+      c              3   .   K   | ]  }|z
  z    y wNr,   ).0r   r_   r   s     r   	<genexpr>z*_csolve_prime_las_vegas.<locals>.<genexpr>g	  s      HQ! Hs   T)	all_roots)r%  r$  r   r+  r   setr   r]   r   popr2   addr
   updater$   r   sorted)r3   r   seedr$  r+  randintrootrf   r   r   r-   r_   s    `         @r   _csolve_prime_las_vegasr:  	  s   p '&tnG5DAq61q5!Q+AaAr"AaAr"#G
KKMq6Q;q6Q;HHfQqT1o%!,q01q6Q;1q/C!s
QAQ!a%[Q&AKK H A!s
!2AFH H 1q5!AAq6AEa<Ar:AaAr*Aq!Q#A3q6"CF"q!vaAr2156  4 $<r!   c           
         ddl m} | D cg c]  }t        t        |             }}t	        t        |      |z
        D ]  }|||z   dz
  xx   ||   z  cc<   d||<    t        ||      }d}|t        |      k  rB|t        |      |z
  dz
     dk(  r+|dz  }|t        |      k  r|t        |      |z
  dz
     dk(  r+|r
|d|  }dg}ng }|g k(  rt        t	        |            }	nOt        |      dz  |k  r|t        ||      z   }	n.|t	        |      D cg c]  }t        ||||      dk(  s| c}z   }	|dk(  r|	S g }
t        t        |	dgt        |	      z              }|rj|j                         \  }}||k(  r|
j                  |       n=|dz   }||z  }|j                  t        ||||       D cg c]  }|||z  z   |f c}       |rjt        |
      S c c}w c c}w c c}w )a   Solutions of `f(x) \equiv 0 \pmod{p^e}`.

    Parameters
    ==========

    f : polynomial
    p : prime number
    e : positive integer

    Returns
    =======

    list[int]
        a list of solutions, sorted in ascending order
        by integers in the range [1, p**e). The same value
        does not exist in the list even if there is
        a multiple solution. If no solution exists, returns [].

    Examples
    ========

    >>> from sympy.polys.galoistools import csolve_prime
    >>> csolve_prime([1, 1, 7], 3, 1)
    [1]
    >>> csolve_prime([1, 1, 7], 3, 2)
    [1, 4, 7]

    Solutions [7, 4, 1] (mod 3**2) are generated by ``_raise_mod_power()``
    from solution [1] (mod 3).
    r   r#  r0   Nr+   )r%  r$  r	   r   rI   r2   r@   rB   r:  r   r   r3  r$   r   r)  r6  )r3   r   r   r$  rU   rf   rp   r<   	root_zeroX1Xr&   r   r   r   psr   s                    r   csolve_primer@  x	  s   > ' SV A 3q6A: 	!a%!)!! 	AA	A
c!f*3q6A:>*a/	Q c!f*3q6A:>*a/crFC		Bw%(^	QQ 0A66U1XKAq"1E1J!KKAv	
ASaSR[!"A
uuw16HHQKQBABHH.>q!Q.JKq1R4xnKL  !9G 	!, L Ls   GG+G0G c           
         ddl m} ddlm}  ||      }|j	                         D cg c]  \  }}t        | ||       }}}t        t        t        |            }g g}	|D ]  }
|	D cg c]  }|
D ]  }||gz   
  }	}}  |j	                         D cg c]  \  }}t        ||       }}}t        |	D cg c]  }t        |||       c}      S c c}}w c c}}w c c}}w c c}w )a  
    To solve f(x) congruent 0 mod(n).

    n is divided into canonical factors and f(x) cong 0 mod(p**e) will be
    solved for each factor. Applying the Chinese Remainder Theorem to the
    results returns the final answers.

    Examples
    ========

    Solve [1, 1, 7] congruent 0 mod(189):

    >>> from sympy.polys.galoistools import gf_csolve
    >>> gf_csolve([1, 1, 7], 189)
    [13, 49, 76, 112, 139, 175]

    See Also
    ========

    sympy.ntheory.residue_ntheory.polynomial_congruence : a higher level solving routine

    References
    ==========

    .. [1] 'An introduction to the Theory of Numbers' 5th Edition by Ivan Niven,
           Zuckerman and Montgomery.

    r   r#  r   )r%  r$  r   r   itemsr@  rB   rC   r~   powr6  r    )r3   rK   r$  r   Pr   r   r>  poolspermspoolr   ydist_factorspers                  r   	gf_csolverK  	  s    : ''!A+,779541aaA	5A5UAEDE 7"'6Q6AaS6667*+'')4$!QC1I4L4EBS6#|R0BCC 	6 74Bs   C(CC6C#r.  )T)F)r0   )`__doc__mathr   r  r   r  r   sympy.core.randomr   r   sympy.external.gmpyr   r	   r
   sympy.polys.polyconfigr   sympy.polys.polyerrorsr   sympy.polys.polyutilsr   r    r'   r)   r.   r4   r8   r:   r>   r@   rD   rM   rQ   rS   rV   rX   r[   r]   r`   rb   ri   rk   rr   rw   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   r   r   r   r   r   r   r   r  r  r  r
  r  r  r  r  r  r  r!  r)  r:  r@  rK  r,   r!   r   <module>rS     s   G 3 3 / 7 7 ( 6 /*Z.b"J*$((8* ("8: ,)"88((2" 9F 9F>(V//"83,l!"$N(6((#J@#J".b ( . .?D22<0.":65,nE"&*Z)X  4<00Vr%P;|)2X6r=2@JX<2~2,2, :=&@( =F%-PZzCL&Dr!   