
    \h)                     r   S r SSKrSSKJr  SSKJr  SSKJr  SSKJ	r	  SSK
Jr  SSKJr  SS	KJrJr  SS
KJr  SSKJr  SSKJr  \S:X  a  S/r\S:X  a9  SSKr\R2                  R5                  S5      trrr\" \5      \" \5      4S:  a  SrOSrS rS r S r!\\" SS/S9 " S S\	\5      5       5       r"\"=r#r$g)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                    ^ ^^^ [         R                  mT" T 5      m [        R                  m[        R                  m T" ST 5        UU U4S jnU U4S jnX4$ ! [
         a     gf = f)Nr   )NNc                 V   >  T" U T5      $ ! [          a    T" T" U 5      T5      s $ f = fN	TypeError)xindexmodnmods    W/var/www/auris/envauris/lib/python3.13/site-packages/sympy/polys/domains/finitefield.pyctx&_modular_int_factory_nmod.<locals>.ctx/   s4    	'3< 	'a#&&	's    ((c                    > T" U T5      $ r    )csr   	nmod_polys    r   poly_ctx+_modular_int_factory_nmod.<locals>.poly_ctx5   s    S!!    )operatorr   r   r   r!   OverflowError)r   r   r"   r   r   r!   s   `  @@@r   _modular_int_factory_nmodr'   "   s]    NNE
*C::DIQ'" =  s   	A 
A&%A&c                    ^^^^ [         R                  m[        R                  " U 5      m[        R                  " U 5      m[        R
                  mUU4S jnUU4S jnX4$ )Nc                 R   >  T" U 5      $ ! [          a    T" T" U 5      5      s $ f = fr   r   )r   fctxr   s    r   r   *_modular_int_factory_fmpz_mod.<locals>.ctxA   s.    	"7N 	"a>!	"s    &&c                    > T" U T5      $ r   r   )r    	fctx_polyfmpz_mod_polys    r   r"   /_modular_int_factory_fmpz_mod.<locals>.poly_ctxH   s    R++r$   )r%   r   r   fmpz_mod_ctxfmpz_mod_poly_ctxr.   )r   r   r"   r*   r-   r.   r   s      @@@@r   _modular_int_factory_fmpz_modr2   ;   sK    NNEc"D'',I''M", =r$   c                     UR                  U 5      n Su  pEn[        b4  U R	                  5       (       a  Sn[        U 5      u  pEUc  [        U 5      u  pEUc  [        XX#5      nS nXEU4$ ! [         a    [        SU -  5      ef = f)Nz"modulus must be an integer, got %s)NNFT)convertr   
ValueErrorr   is_primer'   r2   r   )r   dom	symmetricselfr   r"   is_flints          r   _modular_int_factoryr;   N   s    Ekk# 0C8 S\\^^ 2#6;9#>MC
{ $Ci>(""/  E=CDDEs   A( (Bpythongmpy)modulesc                      \ rS rSrSrSrSrS=rrSr	Sr
SrSrSrS#S jr\S 5       r\S	 5       rS
 rS rS rS rS rS rS rS rS rS rS rS rS$S jrS$S jrS$S jr S$S jr!S$S jr"S$S jr#S$S jr$S$S jr%S$S jr&S r'S  r(S! r)S"r*g)%r   l   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                 .   SSK Jn  UnUS::  a  [        SU-  5      e[        XX 5      u  pVnXPl        X`l        Xpl        U R	                  S5      U l        U R	                  S5      U l        X@l	        Xl
        X l        [        U R                  5      U l        g )Nr   )ZZz*modulus must be a positive integer, got %s   )sympy.polys.domainsrC   r5   r;   dtype	_poly_ctx	_is_flintzerooner7   r   symtype_tp)r9   r   r8   rC   r7   r   r"   r:   s           r   __init__FiniteField.__init__   s~    *!8ICOPP"6s"Qx
!!JJqM	::a=		?r$   c                     U R                   $ r   )rM   r9   s    r   tpFiniteField.tp       xxr$   c                 d    [        U SS 5      nUc  SSKJn  U" U R                  5      =U l        nU$ )N	_is_fieldr   )isprime)getattrsympy.ntheory.primetestrW   r   rV   )r9   is_fieldrW   s      r   is_FieldFiniteField.is_Field   s3    4d37(/(99DNXr$   c                      SU R                   -  $ )NzGF(%s)r   rQ   s    r   __str__FiniteField.__str__   s    $((""r$   c                     [        U R                  R                  U R                  U R                  U R
                  45      $ r   )hash	__class____name__rF   r   r7   rQ   s    r   __hash__FiniteField.__hash__   s,    T^^,,djj$((DHHMNNr$   c                     [        U[        5      =(       a9    U R                  UR                  :H  =(       a    U R                  UR                  :H  $ )z0Returns ``True`` if two domains are equivalent. )
isinstancer   r   r7   )r9   others     r   __eq__FiniteField.__eq__   s;    %- <HH		!<&*hh%))&;	<r$   c                     U R                   $ )z*Return the characteristic of this domain. r^   rQ   s    r   characteristicFiniteField.characteristic   rT   r$   c                     U $ )z*Returns a field associated with ``self``. r   rQ   s    r   	get_fieldFiniteField.get_field  s    r$   c                 6    [        U R                  U5      5      $ )z!Convert ``a`` to a SymPy object. )r   to_intr9   as     r   to_sympyFiniteField.to_sympy  s    DKKN++r$   c                 ,   UR                   (       a3  U R                  U R                  R                  [        U5      5      5      $ [	        U5      (       a3  U R                  U R                  R                  [        U5      5      5      $ [        SU-  5      e)z0Convert SymPy's Integer to SymPy's ``Integer``. zexpected an integer, got %s)
is_IntegerrF   r7   intr   r   rt   s     r   
from_sympyFiniteField.from_sympy
  sc    <<::dhhnnSV455]]::dhhnnSV455 !>!BCCr$   c                 ~    [        U5      nU R                  (       a   X R                  S-  :  a  X R                  -  nU$ )z,Convert ``val`` to a Python ``int`` object.    )rz   rK   r   )r9   ru   avals      r   rs   FiniteField.to_int  s0    1v88xx1},HHDr$   c                     [        U5      $ )z#Returns True if ``a`` is positive. )boolrt   s     r   is_positiveFiniteField.is_positive  s    Awr$   c                     g)z'Returns True if ``a`` is non-negative. Tr   rt   s     r   is_nonnegativeFiniteField.is_nonnegative  s    r$   c                     g)z#Returns True if ``a`` is negative. Fr   rt   s     r   is_negativeFiniteField.is_negative"  s    r$   c                     U(       + $ )z'Returns True if ``a`` is non-positive. r   rt   s     r   is_nonpositiveFiniteField.is_nonpositive&  s	    ur$   c                 ~    U R                  U R                  R                  [        U5      UR                  5      5      $ z.Convert ``ModularInteger(int)`` to ``dtype``. )rF   r7   from_ZZrz   K1ru   K0s      r   from_FFFiniteField.from_FF*  s(    xxs1vrvv677r$   c                 ~    U R                  U R                  R                  [        U5      UR                  5      5      $ r   )rF   r7   from_ZZ_pythonrz   r   s      r   from_FF_pythonFiniteField.from_FF_python.  s*    xx--c!fbff=>>r$   c                 V    U R                  U R                  R                  X5      5      $ z'Convert Python's ``int`` to ``dtype``. rF   r7   r   r   s      r   r   FiniteField.from_ZZ2       xx--a455r$   c                 V    U R                  U R                  R                  X5      5      $ r   r   r   s      r   r   FiniteField.from_ZZ_python6  r   r$   c                 Z    UR                   S:X  a  U R                  UR                  5      $ gz,Convert Python's ``Fraction`` to ``dtype``. rD   Ndenominatorr   	numeratorr   s      r   from_QQFiniteField.from_QQ:  (    ==A$$Q[[11 r$   c                 Z    UR                   S:X  a  U R                  UR                  5      $ gr   r   r   s      r   from_QQ_pythonFiniteField.from_QQ_python?  r   r$   c                     U R                  U R                  R                  UR                  UR                  5      5      $ )z.Convert ``ModularInteger(mpz)`` to ``dtype``. )rF   r7   from_ZZ_gmpyvalr   s      r   from_FF_gmpyFiniteField.from_FF_gmpyD  s*    xx++AEE266:;;r$   c                 V    U R                  U R                  R                  X5      5      $ )z%Convert GMPY's ``mpz`` to ``dtype``. )rF   r7   r   r   s      r   r   FiniteField.from_ZZ_gmpyH  s     xx++A233r$   c                 Z    UR                   S:X  a  U R                  UR                  5      $ g)z%Convert GMPY's ``mpq`` to ``dtype``. rD   N)r   r   r   r   s      r   from_QQ_gmpyFiniteField.from_QQ_gmpyL  s&    ==A??1;;// r$   c                     UR                  U5      u  p4US:X  a*  U R                  U R                  R                  U5      5      $ g)z'Convert mpmath's ``mpf`` to ``dtype``. rD   N)to_rationalrF   r7   )r   ru   r   pqs        r   from_RealFieldFiniteField.from_RealFieldQ  s9    ~~a 688BFFLLO,, r$   c                     U R                   U R                  U* 4 Vs/ s H  n[        U5      PM     nn[        X0R                  U R
                  5      (       + $ s  snf )z7Returns True if ``a`` is a quadratic residue modulo p. )rJ   rI   rz   r
   r   r7   )r9   ru   r   polys       r   	is_squareFiniteField.is_squareX  sL     "&499qb 9: 91A 9:#D((DHH=== ;s   Ac                 l   U R                   S:X  d  US:X  a  U$ U R                  U R                  U* 4 Vs/ s H  n[        U5      PM     nn[	        X0R                   U R
                  5       H@  n[        U5      S:X  d  M  US   U R                   S-  ::  d  M,  U R                  US   5      s  $    gs  snf )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``.
r~   r   rD   N)r   rJ   rI   rz   r	   r7   lenrF   )r9   ru   r   r   factors        r   exsqrtFiniteField.exsqrt^  s     88q=AFH!%499qb 9: 91A 9:#D((DHH=F6{aF1IQ$>zz&),, > 	 ;s   B1)
rV   rH   rG   rM   r7   rF   r   rJ   rK   rI   )Tr   )+rd   
__module____qualname____firstlineno____doc__repaliasis_FiniteFieldis_FFis_Numericalhas_assoc_Ringhas_assoc_Fieldr7   r   rN   propertyrR   r[   r_   re   rj   rm   rp   rv   r{   rs   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __static_attributes__r   r$   r   r   r   l   s    Vp CE!!NULNO
C
C#(    #O<
,D8?662
2
<40
->r$   )%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_rz   r'   r2   r;   r   rA   GFr   r$   r   <module>r      s    4  , 8 ) + D 9 C 1 " 8 7% 7 **005FFQFS[!F*E2&#< Xv./%  0 D  Rr$   