Ë
    7^(h–ß  ã                   ó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
             úU/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/sympy/polys/galoistools.pyÚgf_crtr       sv   € ôD 	ˆQ�a—e‘eÔ€AØ	�‰€Aä�A�q“	ò ‰ˆˆ1Ø�‰FˆØ—'‘'˜!˜Q“-‰ˆˆ1ˆaØ	ˆQ��!‘�a‘‰[Ñ‰ðð
 ˆq‰5€Ló    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 ˆr€q€AÜˆQ�a—e‘eÔ€Aàò +ˆØ	�‰��a‘ÔØ	�‰�—‘˜˜2™ Ó" 1Ñ%¨Ñ)Õ*ð+ð ˆa�ˆ7€Nr!   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  1“oò ‰
ˆˆ1ˆa�Ø	ˆQ��!‘�a‘‰[Ñ‰ðð ˆq‰5€Lr!   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‚{Øˆà�1‰uˆ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   € ô ˆq‹6�A‰:Ð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   € ñ Ø�v‰vˆà�‰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   € ñ Ø�v‰vˆà�‰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àò ˆÙÙà�‰F‰Að	ð ˆQˆRˆ5€Lr!   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 ›“O QÓ'Ð'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ª   € ô ˆq�v‰v‹x‹=˜"€q€Aä�!”ZÔ Ü�q˜"˜bÓ!ò 	+ˆAØ�H‰H�Q—U‘U˜1˜aŸf™fÓ%¨Ñ)Õ*ñ	+ð ‰ˆä�q˜"˜bÓ!ò 	.ˆAØ�H‰H�Q—U‘U˜A˜4 §¡Ó(¨1Ñ,Õ-ð	.ô �A�q‹>Ð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   € ô ˜!“˜b€v€Aä�1�a˜!‘e‹_ò ˆÙÜ�q˜˜Q™‘x Ó#‰Aà�!�a‘%‘ˆAâØˆF�1ŠIðð €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   € ô �A�q‹>Ð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   € ð &'Ö(˜EˆeˆV�a‹ZÒ(Ð(ùÒ(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‰àˆr‰U�Q‰Y˜!‰Oˆäˆq‹6�AŠ:Ø�S�b�6˜Q˜C‘<ÐáØˆ	àˆ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‰àˆr‰U�Q‰Y˜!‰Oˆäˆq‹6�AŠ:Ø�S�b�6˜Q˜C‘<ÐáØˆ	àˆ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   € ô ˜˜AŸH™H Q¨›N¨A¨qÓ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à	ˆR‚xÜ´#°a¸³)×=©$¨!¨Q˜1˜q™5 A›+Ó=Ó>Ð>ä��R‘‹Lˆà�Š7Ø�R�a�5˜!˜A˜B˜%ˆq‰Aà�R�a�5˜!˜A˜B˜%ˆqˆAà¬S°°A«Y×8¡T Q¨�a˜!‘e˜q“[Ó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à	ˆR‚xÜ´#°a¸³)×=©$¨!¨Q˜1˜q™5 A›+Ó=Ó>Ð>ä��R‘‹Lˆà�Š7Ø�R�a�5˜!˜A˜B˜%ˆq‰Aä˜!˜B˜Q˜%  AÓ&¨¨!¨"¨ˆqˆAà¬S°°A«Y×8¡T Q¨�a˜!‘e˜q“[Ó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ä�1�b˜1‘fÓò ˆØ—‘ˆä”s˜1˜a "™f“~¤s¨1¨b£z°A¡~Ó6ò 	#ˆAØ�Q�q‘T˜!˜A ™E™(‘]Ñ"‰Eð	#ð �q‰yˆˆ!Šðô �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ä�1�b˜1‘fÓò ˆØ—‘ˆä�1�a˜"‘f‹~ˆÜ�1�b‹zˆà�4‰K˜!‰Oˆà�a˜1‘f‰}˜qÑ ˆä�t˜T A™XÓ&ò 	#ˆAØ�Q�q‘T˜!˜A ™E™(‘]Ñ"‰Eð	#ð 	�‰ˆàˆqŠ5Ø�T˜A‘X‘;ˆDØ�T˜1‘WÑˆEà�q‰yˆˆ!Šð'ô* �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    € ô �!”V˜A˜q ! 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    € ô �!”V˜A˜q ! 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à�U‰Uˆà	ˆ€Aàò ‰ˆˆ1Ü�1�a˜˜AÓˆÜ�1�a˜˜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ŠØ�1ˆuˆà
�(‰(�1�Q‘4˜Ó
€Cä�Q“˜˜b™ " q¡&ˆ2€r€Aä�1�b˜1‘fÓò 	ˆØ�!‘ˆä”s˜1˜b 1™f“~¤s¨2°©6°2£¸Ñ':Ó;ò 	/ˆAØ�Q�q˜1‘u˜r‘z‘] Q r¨A¡v¡YÑ.Ñ.‰Eð	/ð �Š7Ø�S‰LˆEà�q‰yˆˆ!Šð	ð ˆWˆb�1‰fˆ:”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ŠØˆ	à
�(‰(�1�Q‘4˜Ó
€Cà‘!��b˜2‘g˜r A™vˆ2€r€Aä�1�b˜1‘fÓò !ˆØ�!‘ˆä”s˜1˜b 1™f“~¤s¨2°©6°2£¸Ñ':Ó;ò 	/ˆAØ�Q�q˜1‘u˜r‘z‘] Q r¨A¡v¡YÑ.Ñ.‰Eð	/ð ˜‘˜qÑ ˆˆ!Šð!ð ˆWˆb�1‰fˆ:Ð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Ó�D€A€qáØˆä! ! 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    € ñ Øˆà�A—F‘F�8˜A‘:‰~Ð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�"ˆv�q˜!˜˜�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à
ØˆqŠ5Ü�q˜!˜Q Ó"ˆAØ�‰FˆAà	ˆa‰ˆáØð €Hô �1�a˜‹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ØˆA‚vØˆ	Ø	
ˆˆA‰€AØˆ3€A€a�DØˆ1‚uÜ�q˜!“ò 	(ˆAÜ˜A˜a !™e™H a¨Ó+ˆCÜ˜#˜q ! QÓ'ˆAˆaŠDð	(ð €Hð 
ˆQŠÜ˜1Ÿ5™5 !§&¡&˜/¨1¨a°°AÓ6ˆˆ!‰Ü�q˜!“ò 	)ˆAÜ˜!˜A ™E™( A a¡D¨!¨QÓ/ˆAˆa‰DÜ˜!˜A™$  1 aÓ(ˆAˆaŠDð	)ð €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ÒÜ�1�a˜˜AÓˆÙØˆ	Ü�!‹€AØ
ˆB‰%ˆ€BÜ�1�a˜!‘e‹_ò !ˆÜ˜!˜A™$  ! a¡%¡¨!¨QÓ/ˆÜ�B˜˜1˜aÓ ‰ð!ð €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Ü�1�a‹[ò ˆÜ˜Q  1 a¨Ó+ˆÜ�1�a˜˜AÓˆÜ�1�a˜˜AÓ‰ðô
 �Q˜˜Q™ ™
 A q¨!Ó
,€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˜˜A˜qÓ!Ð!Ø	
ˆaŠÜ”f˜Q  1“o q¨!¨QÓ/Ð/à	
�‰ˆ€Aà
ØˆqŠ5Ü�q˜!˜Q Ó"ˆAÜ�q˜!˜Q Ó"ˆAØ�‰FˆAà	ˆa‰ˆáØð
 €Hô �1�a˜‹OˆÜ�1�a˜˜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   € ñ Ø”&˜˜A˜q !Ó$ˆ1ˆò ô �A�q˜!Ó˜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Øˆ	äŒv�a˜˜A˜qÓ!Ü�a˜˜A˜qÓ! 1 aó	)€Aô �A�q˜!Ó˜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àŒv�a˜˜A˜qÓ!Ü�1�a˜˜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Ó�F€BˆÜ�a˜˜AÓ�F€BˆáØ�A—H‘H˜R “OÐ$ bÐ(Ð(ÙØ—‘˜˜Q“Ð  " bÐ(Ð(à�h‰h�r˜1‹oÐ ˆ€BØ�!—(‘(˜2˜q“/Ð"ˆ€Bà
Ü�b˜"˜a Ó#‰ˆˆ1áØä  1 aÓ(¨"ˆ‰ˆˆR�"à�h‰h�r˜1‹oˆä�r˜2˜q ! QÓ'ˆÜ�r˜2˜q ! QÓ'ˆä˜q # q¨!Ó,¨bˆBˆÜ˜q # q¨!Ó,¨bˆBˆð ð  ˆr�2ˆ:Ð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   € ñ Ø�v‰v�rˆzÐàˆq‰Tˆà�8‰8�BŒ<Ø”t˜A“w�;Ðà”} Q¨¨A¨qÓ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à�F‰Fˆ8�B‰;˜€q€Aà�3�B�ò ˆØ‘�1“‰ˆØ�‰
ˆáØˆAˆb�1‰f‰Ià	ˆ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>   € ð �V‰V€Fàò ˆØ�!‰ˆØ�!‰ˆØ�!‰‰ðð
 €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#   € ð +,Ö- QŒW�Q˜˜1˜aÕ Ò-Ð-ùÒ-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}   € ô ˆ1ƒv�‚{Üœ ¤E¨!¨Q£K°°AÓ6Ð7Ó8Ð8áØˆ	à	
ˆ1‰ˆ€AàˆqˆrˆUò &ˆÜ�1�a˜˜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   € ñ Øˆ	àˆa‰Dˆ6€DàˆqˆrˆUò %ˆÜ�d˜A˜q !Ó$ˆÜ˜T 1 a¨Ó+ˆÜ�d˜A˜q !Ó$‰ð%ð
 €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àˆ1‚uÜ�1�a˜˜AÓˆØ‰àˆØˆàˆ!�G€Aá
Ü�1”n Q¨¨1¨a°Ó3°Q¸Ó:ˆÜ˜1˜a  A qÓ)ˆàˆqŠ5Ü�qœ.¨¨A¨q°!°QÓ7¸¸AÓ>ˆAÜ˜q ! Q¨¨1Ó-ˆAà	ˆa‰ˆò ô ˜!˜Q  1 aÓ(¨!Ð+Ð+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Ü�1�a‹[ò ˆÜ˜Q  1 a¨Ó+ˆÜ�1�a˜˜AÓˆÜ�1�a˜˜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Ø�E‰Eˆ7´u¸QÀ³{ÖD°!‘qœœW Q¨›^Ó,Õ-Ò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ÓˆÜ˜A˜q !Ô$ØˆHð r!   c                 óœ  — t        | «      }|dk  ryt        | ||«      \  }} |dk  r�t        |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àˆA‚vØä�A�q˜!Ó�D€A€qØˆ1‚uÜ˜AŸE™E 1§6¡6˜?¨A¨q°!°QÓ7Ð7ˆˆAä�q˜!˜Q™$“ò 	ˆAÜ�q˜1Ÿ5™5 !§&¡&˜/¨1¨aÓ0ˆAä�a˜˜A˜qÓ! a§e¡e WÒ,Ü" 1 a¨¨A¨qÓ1‘áð	ð" ô ' q¨!¨QÓ/ˆÜ  !§%¡%¨¯© °!°Q¸¸1Ó=Ð=ˆˆAÜ�q˜!˜Q™$“ò 	ˆAÜ�q˜1Ÿ5™5 !§&¡&˜/¨1¨aÓ0ˆAÜ�a˜˜A˜qÓ! a§e¡e WÒ,Ü$ Q¨¨1¨a°Ó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àˆA‚vØä�A�q˜!Ó�D€A€qà	
�‰�—‘ˆ€Aå'á'¨›lÖ,˜��1“Ð,€GÐ,ä" 1 a¨Ó+€AØ	ˆ!‰€Aä�1�a‹[ò ,ˆØ�‰<Ü�q˜!˜Q Ó"ˆAä�a˜˜A˜qÓ! a§e¡e WÒ,Ùä˜Q  1 a¨Ó+‰ð,ð �‰6€Mùò -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ô !  A qÓ)ˆà€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   € ô  �A�q˜!Ó�D€A€qáØä�aœ  A qÓ)¨1¨aÓ0°Q·U±U°GÑ;Ð;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   € ô ˜˜A˜qÓ!�F€A€sà	
�‰ˆ€Aàò ‰ˆˆ1Ü�1�a˜˜AÓ‰ðð €Hr!   c                 ó†  — ddg t        |«      f\  }}}}t        | ||«      \  }} t        | «      dk  r|g fS 	 t        | ||«      }	|	g k7  r©t	        | |	||«      }
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 ˜E 2¤s¨1£vÐ-Ñ€A€sˆG�Qä�Q˜˜1Ó�E€Bˆä�ƒ|�aÒØ�2ˆvˆà
Ü�A�q˜!Óˆà�Š7Ü�q˜!˜Q Ó"ˆAÜ�q˜!˜Q Ó"ˆAàˆAà˜Ÿ™�w’,Ü˜1˜a  AÓ&�Ü˜1˜a  AÓ&�ä˜Q“< !Ò#Ø—N‘N A q¨¡s 8Ô,ä   A q¨!Ó,¨a°°Q±�a�1�ð ˜Ÿ™�w“,ð �Q—U‘U�GŠ|Ø‘à�áÜ˜!“ Ñ!ˆAä˜1˜a !™e“_ò �Ø˜˜1™‘v��!’ðð �V�a˜!‘e�9˜a ™cˆq‰Aàð? ñ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›€q€Aà	
�‰ˆ�1—6‘6�(˜A ™EÑ"Ñ"€AÜ	ˆa‹ˆ	�R�D˜!˜a™%‘LÑ €Aä�1�q˜1‘u˜a‘i !‘mÓ$ò 	ˆØ�R‘5�&˜˜2™‘, !Ñ#Ð$ a¨¡eˆAˆä�q˜!“ò 	4ˆAØ�I‰I�q˜˜Q™‘x ! A q b¨1¡f¡I¡+Ñ-°Ñ2Õ3ð	4ð �A’Ü˜2“hˆAˆa�‰d‰Gà‰ð	ð €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Ò!¤3 q£6€q€Aä�1�a‹[ò (ˆØ�Q‘4˜‘7˜QŸU™U‘? aÑ'ˆˆ!‰ˆQŠð(ô �1�a‹[ò 8ˆÜ�q˜!“ò 	ˆAØ�‰t�A‹wÙð	ð à�h‰h�q˜‘t˜A‘w Ó"ˆä�q˜!“ò 	(ˆAØ˜‘t˜A‘w˜s‘{ aÑ'ˆAˆa‰D�ŠGð	(ô �q˜!“ò 	ˆAØ�!‘�Q‘ˆAØ˜‘d˜1‘gˆAˆa‰D�‰GØˆAˆa‰D�ŠGð	ô
 �q˜!“ò 	8ˆAØ�A‹vØ�a‘D˜‘G�ä˜q !›ò 8�AØ  ™t A™w¨¨1©¨a©°©Ñ2°aÑ7�A�a‘D˜’Gñ8ñ		8ð#8ô0 �1�a‹[ò )ˆÜ�q˜!“ò 	)ˆAØ�AŠvØŸ5™5 1 Q¡4¨¡7™?¨aÑ/��!‘�Q’à˜a™D ™G˜8 q™.��!‘�Q’ñ		)ð)ð €Eàò ˆÜˆq�6Ø�L‰L˜�Oðð €LùòU "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  € ô 	�1�a˜Ó€AÜ�!�Q˜Ó€Aä˜!“ò +‰ˆˆ1ÜœœX a›[Ó)Ó*ˆˆ!Šð+ð ˆc€Gä�1”c˜!“fÓò ˆÜ�g“ò 	ˆAØ—‘ˆAà�a“%Ü! ! A¡$¨¨1¨aÓ0�Ü˜1˜a  AÓ&�à˜Ÿ™˜’< A¨¢FØ—N‘N 1Ô%ä˜q ! Q¨Ó*�AØ—N‘N A q 6Ô*ä�w“<¤3 q£6Ò)Ü(¨¸5ÔAÔAà�Q—U‘U‘
�ð �a”%ñ	ðô& ˜¨5Ô1Ð1r!   c           	      ó   — d|j                   |j                  gg }}}t        | ||«      }d|z  t        | «      k  r¢t	        || |||«      }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 ˜Ÿ™˜qŸv™v�¨ˆ'€q€Aä" 1 a¨Ó+€AØ
ˆA‰#”˜1“Ò
Ü˜Q  1 a¨Ó+ˆÜ�1”f˜Q §¡¨¯© °°AÓ6¸¸1Ó=ˆà�—‘�Š<Ø�N‰N˜A˜q˜6Ô"ä�q˜!˜Q Ó"ˆAÜ�q˜!˜Q Ó"ˆAÜ*¨1¨a°Ó3ˆAà	ˆQ‰ˆð ˆA‰#”˜1“Ó
ð 	ˆQ�U‰UˆG‚|Ø˜1œi¨›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  € ð@ ˆc€Gä�ƒ|�qÒØˆä�!‹˜Ñ€AØˆA‚vÜ& q¨!¨QÓ/ˆà	
�‰�—‘ˆ€AÜ
ˆg‹,˜Ò
Ø�Š6ØˆIˆA�ä˜1˜q™5“\ò '�Ü˜q ! Q¨¨1Ó-�Ü˜1˜a  AÓ&‘ð'ô �q˜!˜Q Ó"ˆAØ�!—&‘&˜!Ÿ&™&Ð!Ñ!‰Aä˜!˜a™% !™) Q¨Ó*ˆAÜ˜q ! Q¨¨1¨aÓ0ˆAÜ�qœ-¨¨1¯5©5°!°QÓ7¸¸AÓ>ˆAà�—‘�Š<˜A šFÜ'¨¨1¨a°Ó3Ü#¤F¨1¨a°°AÓ$6¸¸1¸aÓ@ñ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Ü" 1 a¨Ó+€AÜ˜!Ÿ%™% §¡˜¨!¨Q°°1Ó5€Aà
�%‰%�—‘ˆ˜!Ð §¡˜x¨¨Q©Ñ/Ñ/€Aä�1�a˜!‘e‹_ò 4ˆÜ  ! A¡#¡¨¨1¨a°Ó3ˆˆ!Šð4ð ˆQ‰4��2�A�€q€Aà	
ˆˆq�v‰vˆh˜˜A™ÑÑ€Aä�1�a‹[ò 4ˆÜ˜a  A¡™h¨¨1¨a°Ó3ˆˆ!Šð4ð €Gä˜!“ò -‰ˆˆ1Ø—‘ˆw˜˜A™ˆ1ˆàò 	#ˆAÜ�q˜!˜Q Ó"ˆAÜ�q˜!˜Q Ó"ˆAÜ�q˜!˜Q Ó"‰Að	#ô
 �1�a˜˜AÓˆÜ�1�a˜˜AÓˆä˜!“ò 	-ˆAÜ�q˜!˜Q Ó"ˆAÜ�q˜!˜Q Ó"ˆAà�Q—U‘U�GŠ|Ø—‘  1 a¨!¡e¡9¨q¡=Ð1Ô2ä˜!˜Q  1Ó% q¨1¡uˆq‰Añ	-ð-ð( 	ˆQ�U‰UˆG‚|Ø�‰˜œ9 Q›<Ð(Ô)à€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   }nªt        | ||«      }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›€q€AáØˆ	ØˆA‚vØˆsˆ
à��q—u‘u˜aŸf™f�oˆQ€Gä�!�a‘%˜˜AÓ€AàˆA‚vÜ�q˜!˜Q  1Ó%ˆÜ˜˜A˜q ! a¡%¨¨A¨qÓ1°!Ñ4ˆÜ�A�q˜!˜QÓˆÜ�A�r˜1˜aÓ ˆä˜r 1 a¨Ó+Ü˜2˜q ! QÓ'ñ(‰ô ' q¨!¨QÓ/ˆÜ˜!˜Q  1 a¨Ó+ˆÜ�q˜1˜q™5 1™* a¨¨AÓ.ˆä�A�q˜!˜QÓˆÜ�A”} Q¨¯©¨q°!Ó4°a¸Ó;ˆÜ�A”v˜b " a¨Ó+¨Q°Ó2ˆä˜r 1 a¨Ó+Ü˜2˜q ! QÓ'ñ(ä˜2˜q ! 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‰	ˆ�ØÔ$ V¨Q°°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‰	ˆ�Ø”< ¨¨1¨aÓ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Ó�E€Bˆä�ƒ|�aÒØ�2ˆvˆàÒ0”uÐ/Ó0€FàÐÜ! &Ñ)¨!¨Q°Ó2ˆð ˆwˆ;Ðô    1 aÓ(ˆàˆ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Ó�E€Bˆä�ƒ|�aÒØ�2ˆvˆà€Gä˜A˜q !Ó$ QÑ'ò #‰ˆˆ1Ü˜q ! QÓ'¨Ñ*ò 	#ˆAØ�N‰N˜A˜q˜6Õ"ñ	#ð#ð Œ}˜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ƒ   € õ. ,Øˆ1�u�‚zØˆq‰5�AŠ:Üœ˜a›“>Ð!àˆIÙ�A�q‹k�G€A€qˆ!Øˆ1�u�‚zØˆ	Ü38¸³8Ö<¨aˆQ�‰U�a‰Z˜!˜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Ü˜U D¨!Ó,Ð,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 'Ý&Ü�t‹n€GÜ‹5€DÜ�A�q�6˜1˜q™5 ! Q¨Ó+€AÜ�a˜˜A˜rÓ"€Aä�a˜˜A˜rÓ"Ð#€GÚ
Ø�K‰K‹Mˆäˆq‹6�QŠ;ØÜˆq‹6�QŠ;Ø�H‰H”f˜Q˜q™T 1“oÐ%¨¨!©Ñ,¨qÑ0Ô1ØÜˆq‹6�QŠ;Ü˜˜1™˜q“/ˆCØ�!‘�s‘
˜Q‘ˆAØ�Q˜!˜a™%‘[‘ QÑ&ˆAØ�K‰Kô HÙ   A¡¨¨!©¨s©
Ñ!2°AÀÔFôHô HàØñ ˜˜1˜q™5Ó!ˆAÜ˜A˜q˜6 A¨¡E¨a¡<°°A°rÓ:ˆAÜ˜a  A rÓ*ˆAÜ�q˜!˜Q Ó#ˆAØ”3�q“6Ô"œC ›FÕ"Ø—‘˜qÔ!Ø—‘œv a¨¨A¨rÓ2°1Ñ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Ð ä”3�q“6˜A‘:Óò ˆØ	ˆ!ˆa‰%�!‰)‹˜˜!™Ñ‹Øˆˆ!Šðô 	��A‹€Aà	€AØ
Œc�!‹fŠ*˜œ3˜q›6 A™:¨™>Ñ*¨aÒ/Ø	ˆQ‰ˆð Œc�!‹fŠ*˜œ3˜q›6 A™:¨™>Ñ*¨aÓ/áØˆc�ˆrˆFˆØ�C‰	àˆ	ØˆB‚wÜ”%˜“(‹^‰Ü	ˆQ‹�‰�QŠð Ô0°°AÓ6Ñ6‰à¤U¨1£XÖK ´¸¸A¸qÀ"Ó1EÈÓ1Jš!ÒKÑKˆØˆA‚vØˆ	Ø
€AÜŒS��a�Sœ˜R›‘[Ó!Ó"€AÙ
Ø�u‰u‹w‰ˆˆ1Ø�Š6Ø�H‰H�Q�Kà�Q‘ˆBØ�A‘ˆBØ�H‰HÔ.>¸qÀ!ÀQÈÓ.JÖK¨�q˜1˜R™4‘x ’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Ø+,¯7©7«9×5¡4 1 aŒ�a˜˜AÕ	Ð5€AÑ5Ü””U˜A“Ó€EØˆD€EØò 7ˆØ"'×6˜Q°Ò6¨A��a�S“Ð6�Ð6ˆÒ6ð7à*+¯'©'«)×4¡$ ! Q”C˜˜1•IÐ4€LÑ4Ü¸EÖB°S”6˜#˜|¨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ò" 9òF 9òFò>(òV/ò/ò"ò83,òl!ò"$òN(ò6ò(ò(#òJò@#òJò".òb ò( ò. ò.?òD2ò2ò<ò0.ò"ò:ò65,ònòEò"ò&*òZ)ðX  Øñ€òò4<ò0ó0Vòr%òP;ò|)2òX6òr=2ò@JòX<2ò~2ò,2ð, ØØñ€óò:=&ò@ò( =òF%-óPZózCóL&Dr!   