
    sg%                     f   d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZ dd	lmZmZ dd
lmZ ddlmZ ddlmZ edk(  rdgZedk(  r8ddlZej2                  j5                  d      ^ZZZ ee       ee      fdk  rdZndZd Ze eddg       G d de	e                    Z e xZ!Z"y)z.Implementation of :class:`FiniteField` class.     N)GROUND_TYPES)doctest_depends_on)
int_valued)Field)ModularIntegerFactory)SimpleDomain)gf_zassenhausgf_irred_p_rabin)CoercionFailed)public)SymPyIntegerflintFiniteField.)r      c                     t         ^t         j                  t         j                  }t        j                  	 |j                          	  |        	  d         fd}|S t         |||      S # t        $ r t        d z        w xY w# t        $ r          Y Ow xY w# t        $ r  |       fd}Y |S w xY w)Nz"modulus must be an integer, got %sr   c                 T    	  |       S # t         $ r   |             cY S w xY wN	TypeError)xindexmodnmods    R/var/www/html/venv/lib/python3.12/site-packages/sympy/polys/domains/finitefield.pyctxz!_modular_int_factory.<locals>.ctxE   s4    /3<'  /a#../s    ''c                 P    	  |       S # t         $ r   |             cY S w xY wr   r   )r   fctxr   s    r   r   z!_modular_int_factory.<locals>.ctx=   s.    *7N  *a>)*s    %%)r   r   fmpz_mod_ctxoperatorr   convertr   
ValueErrorr   OverflowErrorr   )	r   dom	symmetricselfr   r   r   r   r   s	   `     @@@r   _modular_int_factoryr'   "   s     zz))	I++c"C
	
	/CL/ 
 !c9d;;C  	IACGHH	I  	*C	  		*$D* 
%		*s/   A7 B 	B) 7BB&%B&)CCpythongmpy)modulesc                       e Zd ZdZdZdZdxZZdZdZ	dZ
dZdZd dZe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!dZd!dZd!dZd!dZd!dZ d!dZ!d!dZ"d!dZ#d!dZ$d Z%d Z&d Z'y)"r   a	  Finite field of prime order :ref:`GF(p)`

    A :ref:`GF(p)` domain represents a `finite field`_ `\mathbb{F}_p` of prime
    order as :py:class:`~.Domain` in the domain system (see
    :ref:`polys-domainsintro`).

    A :py:class:`~.Poly` created from an expression with integer
    coefficients will have the domain :ref:`ZZ`. However, if the ``modulus=p``
    option is given then the domain will be a finite field instead.

    >>> from sympy import Poly, Symbol
    >>> x = Symbol('x')
    >>> p = Poly(x**2 + 1)
    >>> p
    Poly(x**2 + 1, x, domain='ZZ')
    >>> p.domain
    ZZ
    >>> p2 = Poly(x**2 + 1, modulus=2)
    >>> p2
    Poly(x**2 + 1, x, modulus=2)
    >>> p2.domain
    GF(2)

    It is possible to factorise a polynomial over :ref:`GF(p)` using the
    modulus argument to :py:func:`~.factor` or by specifying the domain
    explicitly. The domain can also be given as a string.

    >>> from sympy import factor, GF
    >>> factor(x**2 + 1)
    x**2 + 1
    >>> factor(x**2 + 1, modulus=2)
    (x + 1)**2
    >>> factor(x**2 + 1, domain=GF(2))
    (x + 1)**2
    >>> factor(x**2 + 1, domain='GF(2)')
    (x + 1)**2

    It is also possible to use :ref:`GF(p)` with the :py:func:`~.cancel`
    and :py:func:`~.gcd` functions.

    >>> from sympy import cancel, gcd
    >>> cancel((x**2 + 1)/(x + 1))
    (x**2 + 1)/(x + 1)
    >>> cancel((x**2 + 1)/(x + 1), domain=GF(2))
    x + 1
    >>> gcd(x**2 + 1, x + 1)
    1
    >>> gcd(x**2 + 1, x + 1, domain=GF(2))
    x + 1

    When using the domain directly :ref:`GF(p)` can be used as a constructor
    to create instances which then support the operations ``+,-,*,**,/``

    >>> from sympy import GF
    >>> K = GF(5)
    >>> K
    GF(5)
    >>> x = K(3)
    >>> y = K(2)
    >>> x
    3 mod 5
    >>> y
    2 mod 5
    >>> x * y
    1 mod 5
    >>> x / y
    4 mod 5

    Notes
    =====

    It is also possible to create a :ref:`GF(p)` domain of **non-prime**
    order but the resulting ring is **not** a field: it is just the ring of
    the integers modulo ``n``.

    >>> K = GF(9)
    >>> z = K(3)
    >>> z
    3 mod 9
    >>> z**2
    0 mod 9

    It would be good to have a proper implementation of prime power fields
    (``GF(p**n)``) but these are not yet implemented in SymPY.

    .. _finite field: https://en.wikipedia.org/wiki/Finite_field
    FFTFNc                    ddl m} |}|dk  rt        d|z        t        ||||       | _        | j	                  d      | _        | j	                  d      | _        || _        || _        || _	        t        | j
                        | _        y )Nr   )ZZz*modulus must be a positive integer, got %s   )sympy.polys.domainsr.   r"   r'   dtypezerooner$   r   symtype_tp)r&   r   r%   r.   r$   s        r   __init__zFiniteField.__init__   sv    *!8ICOPP)#sItD
JJqM	::a=		?    c                     | j                   S r   )r6   r&   s    r   tpzFiniteField.tp       xxr8   c                      d| j                   z  S )NzGF(%s)r   r:   s    r   __str__zFiniteField.__str__   s    $((""r8   c                     t        | j                  j                  | j                  | j                  | j
                  f      S r   )hash	__class____name__r1   r   r$   r:   s    r   __hash__zFiniteField.__hash__   s,    T^^,,djj$((DHHMNNr8   c                     t        |t              xr4 | j                  |j                  k(  xr | j                  |j                  k(  S )z0Returns ``True`` if two domains are equivalent. )
isinstancer   r   r$   )r&   others     r   __eq__zFiniteField.__eq__   s;    %- <HH		!<&*hh%))&;	<r8   c                     | j                   S )z*Return the characteristic of this domain. r>   r:   s    r   characteristiczFiniteField.characteristic   r<   r8   c                     | S )z*Returns a field associated with ``self``.  r:   s    r   	get_fieldzFiniteField.get_field   s    r8   c                 6    t        | j                  |            S )z!Convert ``a`` to a SymPy object. )r   to_intr&   as     r   to_sympyzFiniteField.to_sympy   s    DKKN++r8   c                    |j                   r3| j                  | j                  j                  t        |                  S t	        |      r3| j                  | j                  j                  t        |                  S t        d|z        )z0Convert SymPy's Integer to SymPy's ``Integer``. zexpected an integer, got %s)
is_Integerr1   r$   intr   r   rP   s     r   
from_sympyzFiniteField.from_sympy   sa    <<::dhhnnSV455]::dhhnnSV455 !>!BCCr8   c                 v    t        |      }| j                  r!|| j                  dz  kD  r|| j                  z  }|S )z,Convert ``val`` to a Python ``int`` object.    )rU   r4   r   )r&   rQ   avals      r   rO   zFiniteField.to_int   s4    1v88txx1},DHHDr8   c                     t        |      S )z#Returns True if ``a`` is positive. )boolrP   s     r   is_positivezFiniteField.is_positive   s    Awr8   c                      y)z'Returns True if ``a`` is non-negative. TrL   rP   s     r   is_nonnegativezFiniteField.is_nonnegative   s    r8   c                      y)z#Returns True if ``a`` is negative. FrL   rP   s     r   is_negativezFiniteField.is_negative   s    r8   c                     | S )z'Returns True if ``a`` is non-positive. rL   rP   s     r   is_nonpositivezFiniteField.is_nonpositive   s	    ur8   c                 ~    | j                  | j                  j                  t        |      |j                              S z.Convert ``ModularInteger(int)`` to ``dtype``. )r1   r$   from_ZZrU   K1rQ   K0s      r   from_FFzFiniteField.from_FF  s(    xxs1vrvv677r8   c                 ~    | j                  | j                  j                  t        |      |j                              S rd   )r1   r$   from_ZZ_pythonrU   rf   s      r   from_FF_pythonzFiniteField.from_FF_python  s*    xx--c!fbff=>>r8   c                 X    | j                  | j                  j                  ||            S z'Convert Python's ``int`` to ``dtype``. r1   r$   rk   rf   s      r   re   zFiniteField.from_ZZ
  "    xx--a455r8   c                 X    | j                  | j                  j                  ||            S rn   ro   rf   s      r   rk   zFiniteField.from_ZZ_python  rp   r8   c                 X    |j                   dk(  r| j                  |j                        S yz,Convert Python's ``Fraction`` to ``dtype``. r/   Ndenominatorrk   	numeratorrf   s      r   from_QQzFiniteField.from_QQ  (    ==A$$Q[[11 r8   c                 X    |j                   dk(  r| j                  |j                        S yrs   rt   rf   s      r   from_QQ_pythonzFiniteField.from_QQ_python  rx   r8   c                     | j                  | j                  j                  |j                  |j                              S )z.Convert ``ModularInteger(mpz)`` to ``dtype``. )r1   r$   from_ZZ_gmpyvalrf   s      r   from_FF_gmpyzFiniteField.from_FF_gmpy  s*    xx++AEE266:;;r8   c                 X    | j                  | j                  j                  ||            S )z%Convert GMPY's ``mpz`` to ``dtype``. )r1   r$   r|   rf   s      r   r|   zFiniteField.from_ZZ_gmpy   s"    xx++Ar233r8   c                 X    |j                   dk(  r| j                  |j                        S y)z%Convert GMPY's ``mpq`` to ``dtype``. r/   N)ru   r|   rv   rf   s      r   from_QQ_gmpyzFiniteField.from_QQ_gmpy$  s&    ==A??1;;// r8   c                     |j                  |      \  }}|dk(  r*| j                  | j                  j                  |            S y)z'Convert mpmath's ``mpf`` to ``dtype``. r/   N)to_rationalr1   r$   )rg   rQ   rh   pqs        r   from_RealFieldzFiniteField.from_RealField)  s;    ~~a 1688BFFLLO,, r8   c                     | j                   | j                  | fD cg c]  }t        |       }}t        || j                  | j
                         S c c}w )z7Returns True if ``a`` is a quadratic residue modulo p. )r3   r2   rU   r
   r   r$   )r&   rQ   r   polys       r   	is_squarezFiniteField.is_square0  sK     "&499qb 9:1A::#D$((DHH=== ;s   Ac                 Z   | j                   dk(  s|dk(  r|S | j                  | j                  | fD cg c]  }t        |       }}t	        || j                   | j
                        D ]<  }t        |      dk(  s|d   | j                   dz  k  s(| j                  |d         c S  yc c}w )zSquare root modulo p of ``a`` if it is a quadratic residue.

        Explanation
        ===========
        Always returns the square root that is no larger than ``p // 2``.
        rX   r   r/   N)r   r3   r2   rU   r	   r$   lenr1   )r&   rQ   r   r   factors        r   exsqrtzFiniteField.exsqrt6  s     88q=AFH!%499qb 9:1A::#D$((DHH= 	-F6{aF1IQ$>zz&),,	- 	 ;s   B()Tr   )(rC   
__module____qualname____doc__repaliasis_FiniteFieldis_FFis_Numericalhas_assoc_Ringhas_assoc_Fieldr$   r   r7   propertyr;   r?   rD   rH   rJ   rM   rR   rV   rO   r\   r^   r`   rb   ri   rl   re   rk   rw   rz   r~   r|   r   r   r   r   rL   r8   r   r   r   Q   s    Vp CE!!NULNO
C
C#  #O<
,D8?662
2
<40
->r8   )#r   r    sympy.external.gmpyr   sympy.utilities.decoratorr   sympy.core.numbersr   sympy.polys.domains.fieldr   "sympy.polys.domains.modularintegerr    sympy.polys.domains.simpledomainr   sympy.polys.galoistoolsr	   r
   sympy.polys.polyerrorsr   sympy.utilitiesr   sympy.polys.domains.groundtypesr   __doctest_skip__r   __version__split_major_minor_rU   r'   r   r,   GFrL   r8   r   <module>r      s    4  , 8 ) + D 9 C 1 " 8 7% 7 **005FFQFS[!F*E,<^ Xv./r% r 0 rj  Rr8   