Ë
    O/æj=J  ã                   ó2  — d 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 dd	lmZ dd
lmZ  G d„ de«      Z G d„ de«      Z G d„ de«      Z G d„ d«      Z G d„ dee«      Z e«       xZe_         G d„ dee«      Z e«       xZe_        y)zDomains of Gaussian type.é    )ÚI)ÚCoercionFailed)ÚZZ)ÚQQ)ÚAlgebraicField)ÚDomain)ÚDomainElement)ÚField)ÚRingc                   óä   ‡ — e Zd ZU dZeed<   eed<   dZdd„Zeˆ fd„«       Z	d„ Z
d„ Zd	„ Zd
„ Zd„ Zd„ Zd„ Zd„ Zed„ «       Zd„ ZeZd„ Zd„ Zd„ ZeZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z d„ Z!ˆ xZ"S )ÚGaussianElementz1Base class for elements of Gaussian type domains.ÚbaseÚ_parent)ÚxÚyc                 ój   — | j                   j                  }| j                   ||«       ||«      «      S ©N)r   ÚconvertÚnew)Úclsr   r   Úconvs       úf/root/repos/pocs/video-evals/.venv/lib/python3.12/site-packages/sympy/polys/domains/gaussiandomains.pyÚ__new__zGaussianElement.__new__   s*   € Ø�x‰x×ÑˆØ�w‰w‘t˜A“w¡ Q£Ó(Ð(ó    c                 óB   •— t         ‰| �  | «      }||_        ||_        |S )z0Create a new GaussianElement of the same domain.)Úsuperr   r   r   )r   r   r   ÚobjÚ	__class__s       €r   r   zGaussianElement.new   s&   ø€ ô ‰g‰o˜cÓ"ˆØˆŒØˆŒØˆ
r   c                 ó   — | j                   S )z4The domain that this is an element of (ZZ_I or QQ_I))r   ©Úselfs    r   ÚparentzGaussianElement.parent!   s   € à�|‰|Ðr   c                 óD   — t        | j                  | j                  f«      S r   )Úhashr   r   r    s    r   Ú__hash__zGaussianElement.__hash__%   s   € Ü�T—V‘V˜TŸV™VÐ$Ó%Ð%r   c                 ó¢   — t        || j                  «      r4| j                  |j                  k(  xr | j                  |j                  k(  S t        S r   )Ú
isinstancer   r   r   ÚNotImplemented©r!   Úothers     r   Ú__eq__zGaussianElement.__eq__(   s;   € Ü�e˜TŸ^™^Ô,Ø—6‘6˜UŸW™WÑ$Ò:¨¯©°5·7±7Ñ):Ð:ä!Ð!r   c                 ó�   — t        |t        «      st        S | j                  | j                  g|j                  |j                  gk  S r   )r'   r   r(   r   r   r)   s     r   Ú__lt__zGaussianElement.__lt__.   s7   € Ü˜%¤Ô1Ü!Ð!Ø—‘˜Ÿ™Ð 5§7¡7¨E¯G©GÐ"4Ñ4Ð4r   c                 ó   — | S r   © r    s    r   Ú__pos__zGaussianElement.__pos__3   s   € Øˆr   c                 óR   — | j                  | j                   | j                   «      S r   ©r   r   r   r    s    r   Ú__neg__zGaussianElement.__neg__6   s   € Ø�x‰x˜Ÿ™˜ $§&¡& Ó)Ð)r   c                 óh   — | j                   j                  ›d| j                  ›d| j                  ›d�S )Nú(z, ú))r   Úrepr   r   r    s    r   Ú__repr__zGaussianElement.__repr__9   s!   € Ø#Ÿ|™|×/Ó/°·³¸¿»Ð@Ð@r   c                 óJ   — t        | j                  j                  | «      «      S r   )Ústrr   Úto_sympyr    s    r   Ú__str__zGaussianElement.__str__<   s   € Ü�4—<‘<×(Ñ(¨Ó.Ó/Ð/r   c                 ó    — t        || «      s	 | j                  j                  |«      }|j                  |j
                  fS # t        $ r Y yw xY w)N)NN)r'   r   r   r   r   r   )r   r*   s     r   Ú_get_xyzGaussianElement._get_xy?   sN   € ä˜% Ô%ð"ØŸ™×+Ñ+¨EÓ2�ð �w‰w˜Ÿ™ÐÐøô "ò "Ù!ð"ús   ŽA Á	AÁAc                 ó’   — | j                  |«      \  }}|�,| j                  | j                  |z   | j                  |z   «      S t        S r   ©r>   r   r   r   r(   ©r!   r*   r   r   s       r   Ú__add__zGaussianElement.__add__H   ó@   € Ø�|‰|˜EÓ"‰ˆˆ1Øˆ=Ø—8‘8˜DŸF™F Q™J¨¯©°©
Ó3Ð3ä!Ð!r   c                 ó’   — | j                  |«      \  }}|�,| j                  | j                  |z
  | j                  |z
  «      S t        S r   r@   rA   s       r   Ú__sub__zGaussianElement.__sub__Q   rC   r   c                 ó’   — | j                  |«      \  }}|�,| j                  || j                  z
  || j                  z
  «      S t        S r   r@   rA   s       r   Ú__rsub__zGaussianElement.__rsub__X   s@   € Ø�|‰|˜EÓ"‰ˆˆ1Øˆ=Ø—8‘8˜A §¡™J¨¨D¯F©F©
Ó3Ð3ä!Ð!r   c                 óÒ   — | j                  |«      \  }}|�L| j                  | j                  |z  | j                  |z  z
  | j                  |z  | j                  |z  z   «      S t        S r   r@   rA   s       r   Ú__mul__zGaussianElement.__mul___   sZ   € Ø�|‰|˜EÓ"‰ˆˆ1Øˆ=Ø—8‘8˜DŸF™F 1™H t§v¡v¨a¡xÑ/°·±¸±¸D¿F¹FÀ1¹HÑ1DÓEÐEä!Ð!r   c                 óÖ   — |dk(  r| j                  dd«      S |dk  rd| z  | }} |dk(  r| S | }|dz  r| n| j                  j                  }|dz  }|r||z  }|dz  r||z  }|dz  }|rŒ|S )Nr   é   é   )r   r   Úone)r!   ÚexpÚpow2Úprods       r   Ú__pow__zGaussianElement.__pow__h   s‘   € Ø�!Š8Ø—8‘8˜A˜q“>Ð!Ø�Š7Ø˜$™  �#ˆDØ�!Š8ØˆKØˆØ˜Q’w‰t D§L¡L×$4Ñ$4ˆØ�‰	ˆÙØ�D‰LˆDØ�QŠwØ˜‘�Ø�A‰IˆCò	 ð
 ˆr   c                 óZ   — t        | j                  «      xs t        | j                  «      S r   )Úboolr   r   r    s    r   Ú__bool__zGaussianElement.__bool__y   s   € Ü�D—F‘F‹|Ò+œt D§F¡F›|Ð+r   c                 ó°   — | j                   dkD  r| j                  dkD  rdS dS | j                   dk  r| j                  dk  rdS dS | j                  dk\  rdS dS )zIReturn quadrant index 0-3.

        0 is included in quadrant 0.
        r   rK   rL   é   )r   r   r    s    r   ÚquadrantzGaussianElement.quadrant|   sY   € ð
 �6‰6�AŠ:ØŸ™ š
�1Ð)¨Ð)Ø�V‰V�aŠZØŸ™ š
�1Ð)¨Ð)àŸ™ !š�1Ð*¨Ð*r   c                 ó†   — 	 | j                   j                  |«      }|j                  | «      S # t        $ r	 t        cY S w xY wr   )r   r   Ú
__divmod__r   r(   r)   s     r   Ú__rdivmod__zGaussianElement.__rdivmod__ˆ   sE   € ð	*Ø—L‘L×(Ñ(¨Ó/ˆEð ×#Ñ# DÓ)Ð)øô ò 	"Ü!Ò!ð	"ús   ‚. ®A ¿A c                 óz   — 	 t         j                  |«      }|j                  | «      S # t        $ r	 t        cY S w xY wr   )ÚQQ_Ir   Ú__truediv__r   r(   r)   s     r   Ú__rtruediv__zGaussianElement.__rtruediv__�   s?   € ð	+Ü—L‘L Ó'ˆEð ×$Ñ$ TÓ*Ð*øô ò 	"Ü!Ò!ð	"ús   ‚( ¨:¹:c                 óB   — | j                  |«      }|t        u r|S |d   S ©Nr   ©rY   r(   ©r!   r*   Úqrs      r   Ú__floordiv__zGaussianElement.__floordiv__˜   ó&   € Ø�_‰_˜UÓ#ˆØœ>Ñ)ˆrÐ4¨r°!©uÐ4r   c                 óB   — | j                  |«      }|t        u r|S |d   S r`   ©rZ   r(   rb   s      r   Ú__rfloordiv__zGaussianElement.__rfloordiv__œ   ó(   € Ø×Ñ˜eÓ$ˆØœ>Ñ)ˆrÐ4¨r°!©uÐ4r   c                 óB   — | j                  |«      }|t        u r|S |d   S ©NrK   ra   rb   s      r   Ú__mod__zGaussianElement.__mod__    re   r   c                 óB   — | j                  |«      }|t        u r|S |d   S rk   rg   rb   s      r   Ú__rmod__zGaussianElement.__rmod__¤   ri   r   )r   )#Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú__annotations__Ú	__slots__r   Úclassmethodr   r"   r%   r+   r-   r0   r3   r8   r<   r>   rB   Ú__radd__rE   rG   rI   Ú__rmul__rQ   rT   rW   rZ   r^   rd   rh   rl   rn   Ú__classcell__)r   s   @r   r   r      sº   ø… Ù;Ø
ƒLØƒOà€Ió)ð óó ðòò&ò"ò5ò
ò*òAò0ð ñ ó ð ò"ð €Hò"ò"ò"ð €Hòò",ò
+ò*ò+ò5ò5ò5ö5r   r   c                   ó    — e Zd ZdZeZd„ Zd„ Zy)ÚGaussianIntegerzîGaussian integer: domain element for :ref:`ZZ_I`

        >>> from sympy import ZZ_I
        >>> z = ZZ_I(2, 3)
        >>> z
        (2 + 3*I)
        >>> type(z)
        <class 'sympy.polys.domains.gaussiandomains.GaussianInteger'>
    c                 ó2   — t         j                  | «      |z  S )úReturn a Gaussian rational.)r\   r   r)   s     r   r]   zGaussianInteger.__truediv__µ   s   € ä�|‰|˜DÓ! %Ñ'Ð'r   c                 ój  — |st        dj                  | «      «      ‚| j                  |«      \  }}|€t        S | j                  |z  | j
                  |z  z   | j                   |z  | j
                  |z  z   }}||z  ||z  z   }d|z  |z   d|z  z  }d|z  |z   d|z  z  }t        ||«      }	|	| |	|z  z
  fS )Nzdivmod({}, 0)rL   )ÚZeroDivisionErrorÚformatr>   r(   r   r   rz   )
r!   r*   r   r   ÚaÚbÚcÚqxÚqyÚqs
             r   rY   zGaussianInteger.__divmod__¹   sÏ   € ÙÜ# O×$:Ñ$:¸4Ó$@ÓAÐAØ�|‰|˜EÓ"‰ˆˆ1Øˆ9Ü!Ð!ð �v‰v�a‰x˜$Ÿ&™& ™(Ñ" T§V¡V G¨A¡I°·±°q±Ñ$8ˆ1ˆØˆa‰C�!�A‘#‰Iˆð �‰c�A‰g˜1˜Q™3ÑˆØ�‰c�A‰g˜1˜Q™3Ñˆä˜B Ó#ˆð �$˜˜5™‘.Ð Ð r   N)ro   rp   rq   rr   r   r   r]   rY   r/   r   r   rz   rz   ©   s   „ ñð €Dò(ó!r   rz   c                   ó    — e Zd ZdZeZd„ Zd„ Zy)ÚGaussianRationala  Gaussian rational: domain element for :ref:`QQ_I`

        >>> from sympy import QQ_I, QQ
        >>> z = QQ_I(QQ(2, 3), QQ(4, 5))
        >>> z
        (2/3 + 4/5*I)
        >>> type(z)
        <class 'sympy.polys.domains.gaussiandomains.GaussianRational'>
    c                 ó"  — |st        dj                  | «      «      ‚| j                  |«      \  }}|€t        S ||z  ||z  z   }t	        | j
                  |z  | j                  |z  z   |z  | j
                   |z  | j                  |z  z   |z  «      S )r|   z{} / 0)r~   r   r>   r(   r‡   r   r   )r!   r*   r   r   r‚   s        r   r]   zGaussianRational.__truediv__Ý   s�   € áÜ# H§O¡O°DÓ$9Ó:Ð:Ø�|‰|˜EÓ"‰ˆˆ1Øˆ9Ü!Ð!Øˆa‰C�!�A‘#‰Iˆä §¡¨¡¨D¯F©F°1©HÑ!4°aÑ 7Ø"&§&¡& ¨¡¨T¯V©V°A©XÑ!5°qÑ 8ó:ð 	:r   c                 óÆ   — 	 | j                   j                  |«      }|st	        dj                  | «      «      ‚| |z  t        j                  fS # t        $ r	 t        cY S w xY w)Nz{} % 0)r   r   r   r(   r~   r   r\   Úzeror)   s     r   rY   zGaussianRational.__divmod__é   s^   € ð	"Ø—L‘L×(Ñ(¨Ó/ˆEñ Ü# H§O¡O°DÓ$9Ó:Ð:à˜‘:œtŸy™yÐ(Ð(øô ò 	"Ü!Ò!ð	"ús   ‚A ÁA ÁA N)ro   rp   rq   rr   r   r   r]   rY   r/   r   r   r‡   r‡   Ñ   s   „ ñð €Dò
:ó)r   r‡   c                   ó~   — e 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„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zy)ÚGaussianDomainz Base class for Gaussian domains.NTc                 ó†   — | j                   j                  } ||j                  «      t         ||j                  «      z  z   S )z!Convert ``a`` to a SymPy object. )Údomr;   r   r   r   )r!   r€   r   s      r   r;   zGaussianDomain.to_sympyþ   s0   € à�x‰x× Ñ ˆÙ�A—C‘C‹yœ1™T !§#¡#›Y™;Ñ&Ð&r   c                 óJ  — |j                  «       \  }}| j                  j                  |«      }|s| j                  |d«      S |j	                  «       \  }}| j                  j                  |«      }|t
        u r| j                  ||«      S t        dj                  |«      «      ‚)z)Convert a SymPy object to ``self.dtype``.r   z{} is not Gaussian)Úas_coeff_AddrŽ   Ú
from_sympyr   Úas_coeff_Mulr   r   r   )r!   r€   Úrr�   r   r   s         r   r‘   zGaussianDomain.from_sympy  s‹   € à�~‰~Ó‰ˆˆ1Ø�H‰H×Ñ Ó"ˆÙØ—8‘8˜A˜q“>Ð!Ø�~‰~Ó‰ˆˆ1Ø�H‰H×Ñ Ó"ˆØ”‰6Ø—8‘8˜A˜q“>Ð!ä Ð!5×!<Ñ!<¸QÓ!?Ó@Ð@r   c                 ó    —  | j                   |Ž S )z$Inject generators into this domain. )Ú	poly_ring)r!   Úgenss     r   ÚinjectzGaussianDomain.inject  s   € àˆt�~‰~˜tÐ$Ð$r   c                 óB   — | j                   |j                  «           }|S r   )ÚunitsrW   )r!   ÚdÚunits      r   Úcanonical_unitzGaussianDomain.canonical_unit  s   € Ø�z‰z˜1Ÿ:™:›<˜-Ñ(ˆØˆr   c                  ó   — y©z/Returns ``False`` for any ``GaussianElement``. Fr/   ©r!   Úelements     r   Úis_negativezGaussianDomain.is_negative  ó   € àr   c                  ó   — yrž   r/   rŸ   s     r   Úis_positivezGaussianDomain.is_positive  r¢   r   c                  ó   — yrž   r/   rŸ   s     r   Úis_nonnegativezGaussianDomain.is_nonnegative   r¢   r   c                  ó   — yrž   r/   rŸ   s     r   Úis_nonpositivezGaussianDomain.is_nonpositive$  r¢   r   c                 ó   —  | |«      S )z%Convert a GMPY mpz to ``self.dtype``.r/   ©ÚK1r€   ÚK0s      r   Úfrom_ZZ_gmpyzGaussianDomain.from_ZZ_gmpy(  ó   € á�!‹uˆr   c                 ó   —  | |«      S ©z.Convert a ZZ_python element to ``self.dtype``.r/   rª   s      r   Úfrom_ZZzGaussianDomain.from_ZZ,  r®   r   c                 ó   —  | |«      S r°   r/   rª   s      r   Úfrom_ZZ_pythonzGaussianDomain.from_ZZ_python0  r®   r   c                 ó   —  | |«      S ©z%Convert a GMPY mpq to ``self.dtype``.r/   rª   s      r   Úfrom_QQzGaussianDomain.from_QQ4  r®   r   c                 ó   —  | |«      S rµ   r/   rª   s      r   Úfrom_QQ_gmpyzGaussianDomain.from_QQ_gmpy8  r®   r   c                 ó   —  | |«      S )z.Convert a QQ_python element to ``self.dtype``.r/   rª   s      r   Úfrom_QQ_pythonzGaussianDomain.from_QQ_python<  r®   r   c                 ó„   — |j                   j                  d   t        k(  r | j                  |j	                  |«      «      S y)z9Convert an element from ZZ<I> or QQ<I> to ``self.dtype``.r   N)ÚextÚargsr   r‘   r;   rª   s      r   Úfrom_AlgebraicFieldz"GaussianDomain.from_AlgebraicField@  s2   € à�6‰6�;‰;�q‰>œQÒØ—=‘= §¡¨Q£Ó0Ð0ð r   )ro   rp   rq   rr   rŽ   Úis_NumericalÚis_ExactÚhas_assoc_RingÚhas_assoc_Fieldr;   r‘   r—   rœ   r¡   r¤   r¦   r¨   r­   r±   r³   r¶   r¸   rº   r¾   r/   r   r   rŒ   rŒ   ô   sj   „ Ù*Ø
€Cà€LØ€Hà€NØ€Oò'ò
Aò%òòòòòòòòòòòó1r   rŒ   c                   ó  — e Zd ZdZeZeZ e ed«       ed«      «      Z e ed«       ed«      «      Z	 e ed«       ed«      «      Z
e	e
e	 e
 fZdZdZdZd„ Zd„ Zd„ Zed	„ «       Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zy)ÚGaussianIntegerRinga{
  Ring of Gaussian integers ``ZZ_I``

    The :ref:`ZZ_I` domain represents the `Gaussian integers`_ `\mathbb{Z}[i]`
    as a :py:class:`~.Domain` in the domain system (see
    :ref:`polys-domainsintro`).

    By default a :py:class:`~.Poly` created from an expression with
    coefficients that are combinations of integers and ``I`` (`\sqrt{-1}`)
    will have the domain :ref:`ZZ_I`.

    >>> from sympy import Poly, Symbol, I
    >>> x = Symbol('x')
    >>> p = Poly(x**2 + I)
    >>> p
    Poly(x**2 + I, x, domain='ZZ_I')
    >>> p.domain
    ZZ_I

    The :ref:`ZZ_I` domain can be used to factorise polynomials that are
    reducible over the Gaussian integers.

    >>> from sympy import factor
    >>> factor(x**2 + 1)
    x**2 + 1
    >>> factor(x**2 + 1, domain='ZZ_I')
    (x - I)*(x + I)

    The corresponding `field of fractions`_ is the domain of the Gaussian
    rationals :ref:`QQ_I`. Conversely :ref:`ZZ_I` is the `ring of integers`_
    of :ref:`QQ_I`.

    >>> from sympy import ZZ_I, QQ_I
    >>> ZZ_I.get_field()
    QQ_I
    >>> QQ_I.get_ring()
    ZZ_I

    When using the domain directly :ref:`ZZ_I` can be used as a constructor.

    >>> ZZ_I(3, 4)
    (3 + 4*I)
    >>> ZZ_I(5)
    (5 + 0*I)

    The domain elements of :ref:`ZZ_I` are instances of
    :py:class:`~.GaussianInteger` which support the rings operations
    ``+,-,*,**``.

    >>> z1 = ZZ_I(5, 1)
    >>> z2 = ZZ_I(2, 3)
    >>> z1
    (5 + 1*I)
    >>> z2
    (2 + 3*I)
    >>> z1 + z2
    (7 + 4*I)
    >>> z1 * z2
    (7 + 17*I)
    >>> z1 ** 2
    (24 + 10*I)

    Both floor (``//``) and modulo (``%``) division work with
    :py:class:`~.GaussianInteger` (see the :py:meth:`~.Domain.div` method).

    >>> z3, z4 = ZZ_I(5), ZZ_I(1, 3)
    >>> z3 // z4  # floor division
    (1 + -1*I)
    >>> z3 % z4   # modulo division (remainder)
    (1 + -2*I)
    >>> (z3//z4)*z4 + z3%z4 == z3
    True

    True division (``/``) in :ref:`ZZ_I` gives an element of :ref:`QQ_I`. The
    :py:meth:`~.Domain.exquo` method can be used to divide in :ref:`ZZ_I` when
    exact division is possible.

    >>> z1 / z2
    (1 + -1*I)
    >>> ZZ_I.exquo(z1, z2)
    (1 + -1*I)
    >>> z3 / z4
    (1/2 + -3/2*I)
    >>> ZZ_I.exquo(z3, z4)
    Traceback (most recent call last):
        ...
    ExactQuotientFailed: (1 + 3*I) does not divide (5 + 0*I) in ZZ_I

    The :py:meth:`~.Domain.gcd` method can be used to compute the `gcd`_ of any
    two elements.

    >>> ZZ_I.gcd(ZZ_I(10), ZZ_I(2))
    (2 + 0*I)
    >>> ZZ_I.gcd(ZZ_I(5), ZZ_I(2, 1))
    (2 + 1*I)

    .. _Gaussian integers: https://en.wikipedia.org/wiki/Gaussian_integer
    .. _gcd: https://en.wikipedia.org/wiki/Greatest_common_divisor

    r   rK   ÚZZ_ITc                  ó   — y)zFor constructing ZZ_I.Nr/   r    s    r   Ú__init__zGaussianIntegerRing.__init__¶  ó   � r   c                 ó0   — t        |t        «      ryt        S ©z0Returns ``True`` if two domains are equivalent. T)r'   rÄ   r(   r)   s     r   r+   zGaussianIntegerRing.__eq__¹  s   € ä�eÔ0Ô1Øä!Ð!r   c                 ó   — t        d«      S )úCompute hash code of ``self``. rÅ   ©r$   r    s    r   r%   zGaussianIntegerRing.__hash__À  ó   € ä�F‹|Ðr   c                  ó   — y©NTr/   r    s    r   Úhas_CharacteristicZeroz*GaussianIntegerRing.has_CharacteristicZeroÄ  ó   € àr   c                  ó   — yr`   r/   r    s    r   Úcharacteristicz"GaussianIntegerRing.characteristicÈ  ó   € Ør   c                 ó   — | S ©z)Returns a ring associated with ``self``. r/   r    s    r   Úget_ringzGaussianIntegerRing.get_ringË  ó   € àˆr   c                 ó   — t         S ©z*Returns a field associated with ``self``. )r\   r    s    r   Ú	get_fieldzGaussianIntegerRing.get_fieldÏ  ó   € äˆr   c                 ól   ‡— | j                  |«      Š|‰z  }t        ˆfd„|D «       «      }|r|f|z   S |S )z€Return first quadrant element associated with ``d``.

        Also multiply the other arguments by the same power of i.
        c              3   ó(   •K  — | ]	  }|‰z  –— Œ y ­wr   r/   )Ú.0r€   r›   s     €r   ú	<genexpr>z0GaussianIntegerRing.normalize.<locals>.<genexpr>Ú  s   øè ø€ Ò* �Q�t•VÑ*ùs   ƒ)rœ   Útuple)r!   rš   r½   r›   s      @r   Ú	normalizezGaussianIntegerRing.normalizeÓ  sA   ø€ ð
 ×"Ñ" 1Ó%ˆØ	ˆT‰	ˆÜÓ* TÔ*Ó*ˆÙ"�ˆt�d‰{Ð)¨Ð)r   c                 ó<   — |r
|||z  }}|rŒ
| j                  |«      S )z-Greatest common divisor of a and b over ZZ_I.)rã   ©r!   r€   r�   s      r   ÚgcdzGaussianIntegerRing.gcdÝ  s&   € áØ�a˜!‘eˆqˆAò à�~‰~˜aÓ Ð r   c                 ó2   — ||z  | j                  ||«      z  S )z+Least common multiple of a and b over ZZ_I.)ræ   rå   s      r   ÚlcmzGaussianIntegerRing.lcmã  s   € à�A‘˜$Ÿ(™( 1 a›.Ñ(Ð(r   c                 ó   — |S )zConvert a ZZ_I element to ZZ_I.r/   rª   s      r   Úfrom_GaussianIntegerRingz,GaussianIntegerRing.from_GaussianIntegerRingç  ó   € àˆr   c                 óš   — | j                  t        j                  |j                  «      t        j                  |j                  «      «      S )zConvert a QQ_I element to ZZ_I.)r   r   r   r   r   rª   s      r   Úfrom_GaussianRationalFieldz.GaussianIntegerRing.from_GaussianRationalFieldë  s+   € à�v‰v”b—j‘j §¡“o¤r§z¡z°!·#±#£Ó7Ð7r   N)ro   rp   rq   rr   r   rŽ   rz   ÚdtyperŠ   rM   Ú	imag_unitr™   r7   Úis_GaussianRingÚis_ZZ_IrÇ   r+   r%   ÚpropertyrÑ   rÔ   rØ   rÜ   rã   ræ   rè   rê   rí   r/   r   r   rÄ   rÄ   F  s½   „ ñbðF €CØ€EÙ‘�A“™˜1›Ó€DÙ
‘�1“‘r˜!“uÓ
€CÙ‘b˜“e™R ›UÓ#€IØ�)˜c˜T I :Ð.€Eà
€Cà€OØ€Gò%ò"òð ñó ðòòòò*ò!ò)òó8r   rÄ   c                   ó
  — e Zd ZdZeZeZ e ed«       ed«      «      Z e ed«       ed«      «      Z	 e ed«       ed«      «      Z
e	e
e	 e
 fZdZdZdZd„ Zd„ Zd„ Zed	„ «       Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zy)ÚGaussianRationalFielda—  Field of Gaussian rationals ``QQ_I``

    The :ref:`QQ_I` domain represents the `Gaussian rationals`_ `\mathbb{Q}(i)`
    as a :py:class:`~.Domain` in the domain system (see
    :ref:`polys-domainsintro`).

    By default a :py:class:`~.Poly` created from an expression with
    coefficients that are combinations of rationals and ``I`` (`\sqrt{-1}`)
    will have the domain :ref:`QQ_I`.

    >>> from sympy import Poly, Symbol, I
    >>> x = Symbol('x')
    >>> p = Poly(x**2 + I/2)
    >>> p
    Poly(x**2 + I/2, x, domain='QQ_I')
    >>> p.domain
    QQ_I

    The polys option ``gaussian=True`` can be used to specify that the domain
    should be :ref:`QQ_I` even if the coefficients do not contain ``I`` or are
    all integers.

    >>> Poly(x**2)
    Poly(x**2, x, domain='ZZ')
    >>> Poly(x**2 + I)
    Poly(x**2 + I, x, domain='ZZ_I')
    >>> Poly(x**2/2)
    Poly(1/2*x**2, x, domain='QQ')
    >>> Poly(x**2, gaussian=True)
    Poly(x**2, x, domain='QQ_I')
    >>> Poly(x**2 + I, gaussian=True)
    Poly(x**2 + I, x, domain='QQ_I')
    >>> Poly(x**2/2, gaussian=True)
    Poly(1/2*x**2, x, domain='QQ_I')

    The :ref:`QQ_I` domain can be used to factorise polynomials that are
    reducible over the Gaussian rationals.

    >>> from sympy import factor, QQ_I
    >>> factor(x**2/4 + 1)
    (x**2 + 4)/4
    >>> factor(x**2/4 + 1, domain='QQ_I')
    (x - 2*I)*(x + 2*I)/4
    >>> factor(x**2/4 + 1, domain=QQ_I)
    (x - 2*I)*(x + 2*I)/4

    It is also possible to specify the :ref:`QQ_I` domain explicitly with
    polys functions like :py:func:`~.apart`.

    >>> from sympy import apart
    >>> apart(1/(1 + x**2))
    1/(x**2 + 1)
    >>> apart(1/(1 + x**2), domain=QQ_I)
    I/(2*(x + I)) - I/(2*(x - I))

    The corresponding `ring of integers`_ is the domain of the Gaussian
    integers :ref:`ZZ_I`. Conversely :ref:`QQ_I` is the `field of fractions`_
    of :ref:`ZZ_I`.

    >>> from sympy import ZZ_I, QQ_I, QQ
    >>> ZZ_I.get_field()
    QQ_I
    >>> QQ_I.get_ring()
    ZZ_I

    When using the domain directly :ref:`QQ_I` can be used as a constructor.

    >>> QQ_I(3, 4)
    (3 + 4*I)
    >>> QQ_I(5)
    (5 + 0*I)
    >>> QQ_I(QQ(2, 3), QQ(4, 5))
    (2/3 + 4/5*I)

    The domain elements of :ref:`QQ_I` are instances of
    :py:class:`~.GaussianRational` which support the field operations
    ``+,-,*,**,/``.

    >>> z1 = QQ_I(5, 1)
    >>> z2 = QQ_I(2, QQ(1, 2))
    >>> z1
    (5 + 1*I)
    >>> z2
    (2 + 1/2*I)
    >>> z1 + z2
    (7 + 3/2*I)
    >>> z1 * z2
    (19/2 + 9/2*I)
    >>> z2 ** 2
    (15/4 + 2*I)

    True division (``/``) in :ref:`QQ_I` gives an element of :ref:`QQ_I` and
    is always exact.

    >>> z1 / z2
    (42/17 + -2/17*I)
    >>> QQ_I.exquo(z1, z2)
    (42/17 + -2/17*I)
    >>> z1 == (z1/z2)*z2
    True

    Both floor (``//``) and modulo (``%``) division can be used with
    :py:class:`~.GaussianRational` (see :py:meth:`~.Domain.div`)
    but division is always exact so there is no remainder.

    >>> z1 // z2
    (42/17 + -2/17*I)
    >>> z1 % z2
    (0 + 0*I)
    >>> QQ_I.div(z1, z2)
    ((42/17 + -2/17*I), (0 + 0*I))
    >>> (z1//z2)*z2 + z1%z2 == z1
    True

    .. _Gaussian rationals: https://en.wikipedia.org/wiki/Gaussian_rational
    r   rK   r\   Tc                  ó   — y)zFor constructing QQ_I.Nr/   r    s    r   rÇ   zGaussianRationalField.__init__s  rÈ   r   c                 ó0   — t        |t        «      ryt        S rÊ   )r'   rô   r(   r)   s     r   r+   zGaussianRationalField.__eq__v  s   € ä�eÔ2Ô3Øä!Ð!r   c                 ó   — t        d«      S )rÌ   r\   rÍ   r    s    r   r%   zGaussianRationalField.__hash__}  rÎ   r   c                  ó   — yrÐ   r/   r    s    r   rÑ   z,GaussianRationalField.has_CharacteristicZero�  rÒ   r   c                  ó   — yr`   r/   r    s    r   rÔ   z$GaussianRationalField.characteristic…  rÕ   r   c                 ó   — t         S r×   )rÅ   r    s    r   rØ   zGaussianRationalField.get_ringˆ  rÝ   r   c                 ó   — | S rÛ   r/   r    s    r   rÜ   zGaussianRationalField.get_fieldŒ  rÙ   r   c                 ó6   — t        | j                  t        «      S )z0Get equivalent domain as an ``AlgebraicField``. )r   rŽ   r   r    s    r   Úas_AlgebraicFieldz'GaussianRationalField.as_AlgebraicField�  s   € ä˜dŸh™h¬Ó*Ð*r   c                 óh   — | j                  «       }|j                  || j                  |«      z  «      S )zGet the numerator of ``a``.)rØ   r   Údenom)r!   r€   rÅ   s      r   ÚnumerzGaussianRationalField.numer”  s)   € à�}‰}‹ˆØ�|‰|˜A §
¡
¨1£Ñ-Ó.Ð.r   c                 ó"  — | j                   j                  «       }| j                   }| j                  «       } |j                   |j                  |j                  «       |j                  |j
                  «      «      } |||j                  «      S )zGet the denominator of ``a``.)rŽ   rØ   rè   rÿ   r   r   rŠ   )r!   r€   r   r   rÅ   Údenom_ZZs         r   rÿ   zGaussianRationalField.denom™  sg   € à�X‰X×ÑÓ ˆØ�X‰XˆØ�}‰}‹ˆØ�2—6‘6˜(˜"Ÿ(™( 1§3¡3›-¨¨¯©°!·#±#«Ó7ˆÙ�H˜bŸg™gÓ&Ð&r   c                 óN   — | j                  |j                  |j                  «      S )zConvert a ZZ_I element to QQ_I.r2   rª   s      r   rê   z.GaussianRationalField.from_GaussianIntegerRing¡  s   € à�v‰v�a—c‘c˜1Ÿ3™3ÓÐr   c                 ó   — |S )zConvert a QQ_I element to QQ_I.r/   rª   s      r   rí   z0GaussianRationalField.from_GaussianRationalField¥  rë   r   c                 óš   — | j                  t        j                  |j                  «      t        j                  |j                  «      «      S )z'Convert a ComplexField element to QQ_I.)r   r   r   ÚrealÚimagrª   s      r   Úfrom_ComplexFieldz'GaussianRationalField.from_ComplexField©  s-   € à�v‰v”b—j‘j §¡Ó(¬"¯*©*°Q·V±VÓ*<Ó=Ð=r   N)ro   rp   rq   rr   r   rŽ   r‡   rî   rŠ   rM   rï   r™   r7   Úis_GaussianFieldÚis_QQ_IrÇ   r+   r%   rò   rÑ   rÔ   rØ   rÜ   rý   r   rÿ   rê   rí   r  r/   r   r   rô   rô   ò  sÃ   „ ñsðh €CØ€EÙ‘�A“™˜1›Ó€DÙ
‘�1“‘r˜!“uÓ
€CÙ‘b˜“e™R ›UÓ#€IØ�)˜c˜T I :Ð.€Eà
€CàÐØ€Gò%ò"òð ñó ðòòòò+ò/ò
'ò òó>r   rô   N)rr   Úsympy.core.numbersr   Úsympy.polys.polyerrorsr   Úsympy.polys.domains.integerringr   Ú!sympy.polys.domains.rationalfieldr   Ú"sympy.polys.domains.algebraicfieldr   Úsympy.polys.domains.domainr   Ú!sympy.polys.domains.domainelementr	   Úsympy.polys.domains.fieldr
   Úsympy.polys.domains.ringr   r   rz   r‡   rŒ   rÄ   rÅ   r   rô   r\   r/   r   r   ú<module>r     s    ðÙ å  Ý 1Ý .Ý 0Ý =Ý -Ý ;Ý +Ý )ôX5�mô X5ôv%!�oô %!ôP )�ô  )÷FO1ñ O1ôdg8˜.¨$ô g8ñR "5Ó!6Ð 6€€Ôôy>˜N¨Eô y>ñx #8Ó"9Ð 9€ÐÕr   