Ë
    täiŽL  ã                  óJ  — 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 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.é    )Úannotations)ÚI)ÚDMP)ÚCoercionFailed)ÚZZ)ÚQQ)ÚAlgebraicField)ÚDomain)ÚDomainElement)ÚField)ÚRingc                  óä   ‡ — e Zd ZU dZded<   d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.r
   ÚbaseÚ_parent)ÚxÚyc                ój   — | j                   j                  }| j                   ||«       ||«      «      S ©N)r   ÚconvertÚnew)Úclsr   r   Úconvs       úr/Volumes/fast/ai/experiments/MLX_z-image/.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__0   s7   € Ü˜%¤Ô1Ü!Ð!Ø—‘˜Ÿ™Ð 5§7¡7¨E¯G©GÐ"4Ñ4Ð4r   c                ó   — | S r   © r"   s    r   Ú__pos__zGaussianElement.__pos__5   s   € Øˆr   c                óR   — | j                  | j                   | j                   «      S r   ©r   r   r   r"   s    r   Ú__neg__zGaussianElement.__neg__8   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__;   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_xyA   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__J   ó@   € Ø�|‰|˜EÓ"‰ˆˆ1Øˆ=Ø—8‘8˜DŸF™F Q™J¨¯©°©
Ó3Ð3ä!Ð!r   c                ó’   — | j                  |«      \  }}|�,| j                  | j                  |z
  | j                  |z
  «      S t        S r   rB   rC   s       r   Ú__sub__zGaussianElement.__sub__S   rE   r   c                ó’   — | j                  |«      \  }}|�,| j                  || j                  z
  || j                  z
  «      S t        S r   rB   rC   s       r   Ú__rsub__zGaussianElement.__rsub__Z   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   rB   rC   s       r   Ú__mul__zGaussianElement.__mul__a   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__j   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__{   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   rM   rN   é   )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   ©r[   r*   ©r#   r,   Úqrs      r   Ú__floordiv__zGaussianElement.__floordiv__š   ó&   € Ø�_‰_˜UÓ#ˆØœ>Ñ)ˆrÐ4¨r°!©uÐ4r   c                óB   — | j                  |«      }|t        u r|S |d   S rb   ©r\   r*   rd   s      r   Ú__rfloordiv__zGaussianElement.__rfloordiv__ž   ó(   € Ø×Ñ˜eÓ$ˆØœ>Ñ)ˆrÐ4¨r°!©uÐ4r   c                óB   — | j                  |«      }|t        u r|S |d   S ©NrM   rc   rd   s      r   Ú__mod__zGaussianElement.__mod__¢   rg   r   c                óB   — | j                  |«      }|t        u r|S |d   S rm   ri   rd   s      r   Ú__rmod__zGaussianElement.__rmod__¦   rk   r   )r   )"Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__Ú	__slots__r   Úclassmethodr   r$   r'   r-   r/   r2   r5   r:   r>   r@   rD   Ú__radd__rG   rI   rK   Ú__rmul__rS   rV   rY   r\   r`   rf   rj   rn   rp   Ú__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)rN   )ÚZeroDivisionErrorÚformatr@   r*   r   r   r|   )
r#   r,   r   r   ÚaÚbÚcÚqxÚqyÚqs
             r   r[   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)rq   rr   rs   rt   r   r   r_   r[   r1   r   r   r|   r|   «   s   „ ñð €Dò(ó!r   r|   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   r[   zGaussianRational.__divmod__ë   s^   € ð	"Ø—L‘L×(Ñ(¨Ó/ˆEñ Ü# H§O¡O°DÓ$9Ó:Ð:à˜‘:œtŸy™yÐ(Ð(øô ò 	"Ü!Ò!ð	"ús   ‚A ÁA ÁA N)rq   rr   rs   rt   r   r   r_   r[   r1   r   r   r‰   r‰   Ó   s   „ ñð €Dò
:ó)r   r‰   c                  ó†   — e Zd ZU dZded<   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.r
   ÚdomTc                ó†   — | j                   j                  } ||j                  «      t         ||j                  «      z  z   S )z!Convert ``a`` to a SymPy object. )r�   r=   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   )ÚunitsrY   )r#   ÚdÚunits      r   Úcanonical_unitzGaussianDomain.canonical_unit  s   € Ø�z‰z˜1Ÿ:™:›<˜-Ñ(ˆØˆr   c                 ó   — y©z/Returns ``False`` for any ``GaussianElement``. Fr1   ©r#   Úelements     r   Úis_negativezGaussianDomain.is_negative  ó   € àr   c                 ó   — yr    r1   r¡   s     r   Úis_positivezGaussianDomain.is_positive  r¤   r   c                 ó   — yr    r1   r¡   s     r   Úis_nonnegativezGaussianDomain.is_nonnegative"  r¤   r   c                 ó   — yr    r1   r¡   s     r   Úis_nonpositivezGaussianDomain.is_nonpositive&  r¤   r   c                ó   —  | |«      S )z%Convert a GMPY mpz to ``self.dtype``.r1   ©ÚK1r‚   ÚK0s      r   Úfrom_ZZ_gmpyzGaussianDomain.from_ZZ_gmpy*  ó   € á�!‹uˆr   c                ó   —  | |«      S ©z.Convert a ZZ_python element to ``self.dtype``.r1   r¬   s      r   Úfrom_ZZzGaussianDomain.from_ZZ.  r°   r   c                ó   —  | |«      S r²   r1   r¬   s      r   Úfrom_ZZ_pythonzGaussianDomain.from_ZZ_python2  r°   r   c                ó   —  | |«      S ©z%Convert a GMPY mpq to ``self.dtype``.r1   r¬   s      r   Úfrom_QQzGaussianDomain.from_QQ6  r°   r   c                ó   —  | |«      S r·   r1   r¬   s      r   Úfrom_QQ_gmpyzGaussianDomain.from_QQ_gmpy:  r°   r   c                ó   —  | |«      S )z.Convert a QQ_python element to ``self.dtype``.r1   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_AlgebraicFieldB  s2   € à�6‰6�;‰;�q‰>œQÒØ—=‘= §¡¨Q£Ó0Ð0ð r   N)rq   rr   rs   rt   ru   Úis_NumericalÚis_ExactÚhas_assoc_RingÚhas_assoc_Fieldr=   r“   r™   rž   r£   r¦   r¨   rª   r¯   r³   rµ   r¸   rº   r¼   rÀ   r1   r   r   rŽ   rŽ   ö   sj   … Ù*Ø	ƒKà€LØ€Hà€NØ€Oò'ò
Aò%òòòòòòòòòòòó1r   rŽ   c                  ób  — e Zd ZdZeZ eej                  ej                  ej                  g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d„ Zed	„ «       Z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   rM   ÚZZ_ITc                 ó   — y)zFor constructing ZZ_I.Nr1   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©NTr1   r"   s    r   Úhas_CharacteristicZeroz*GaussianIntegerRing.has_CharacteristicZeroÈ  ó   € àr   c                 ó   — yrb   r1   r"   s    r   Úcharacteristicz"GaussianIntegerRing.characteristicÌ  ó   € Ør   c                ó   — | S ©z)Returns a ring associated with ``self``. r1   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   r1   )Ú.0r‚   r�   s     €r   Ú	<genexpr>z0GaussianIntegerRing.normalize.<locals>.<genexpr>Þ  s   øè ø€ Ð*¡T �Q�t•V¡Tù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                óê   — | j                   }| j                  }| j                  }| j                   }|r&||z  }||||z  z
  }}||||z  z
  }}||||z  z
  }}|rŒ&| j                  |||«      \  }}}|||fS )z6Return x, y, g such that x * a + y * b = g = gcd(a, b))rO   rŒ   rå   )r#   r‚   rƒ   Úx_aÚx_bÚy_aÚy_br‡   s           r   ÚgcdexzGaussianIntegerRing.gcdexç  s�   € à�h‰hˆØ�i‰iˆØ�i‰iˆØ�h‰hˆÙØ�Q‘ˆAØ�a˜!˜a™%‘iˆqˆAØ˜C ! c¡'™M�ˆCØ˜C ! c¡'™M�ˆCò	 ð —n‘n Q¨¨SÓ1‰ˆˆ3�Ø�C˜ˆ{Ð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.r1   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) rq   rr   rs   rt   r   r�   r   rO   rŒ   Úmodr|   ÚdtypeÚ	imag_unitr›   r9   Úis_GaussianRingÚis_ZZ_IÚis_PIDrÉ   r-   r'   ÚpropertyrÓ   rÖ   rÚ   rÞ   rå   rè   rî   rð   rò   rõ   r1   r   r   rÆ   rÆ   H  sæ   „ ñbðF €CÙ
ˆr�v‰v�r—w‘w §¡Ð'¨Ó
,€CØ€EÙ‘�A“™˜1›Ó€DÙ
‘�1“‘r˜!“uÓ
€CÙ‘b˜“e™R ›UÓ#€IØ�)˜c˜T I :Ð.€Eà
€Cà€OØ€GØ€Fò%ò"òð ñó ðòòòò*ò!òò)òó8r   rÆ   c                  ó^  — e Zd ZdZeZ eej                  ej                  ej                  g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   rM   r^   Tc                 ó   — y)zFor constructing QQ_I.Nr1   r"   s    r   rÉ   zGaussianRationalField.__init__‡  rÊ   r   c                ó0   — t        |t        «      ryt        S rÌ   )r)   rþ   r*   r+   s     r   r-   zGaussianRationalField.__eq__Š  s   € ä�eÔ2Ô3Øä!Ð!r   c                ó   — t        d«      S )rÎ   r^   rÏ   r"   s    r   r'   zGaussianRationalField.__hash__‘  rÐ   r   c                 ó   — yrÒ   r1   r"   s    r   rÓ   z,GaussianRationalField.has_CharacteristicZero•  rÔ   r   c                 ó   — yrb   r1   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Ý   r1   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.r4   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.r1   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)rq   rr   rs   rt   r   r�   r   rO   rŒ   rö   r‰   r÷   rø   r›   r9   Úis_GaussianFieldÚis_QQ_IrÉ   r-   r'   rü   rÓ   rÖ   rÚ   rÞ   r  r
  r	  rò   rõ   r  r1   r   r   rþ   rþ     sâ   „ ñsðh €CÙ
ˆr�v‰v�r—w‘w §¡Ð'¨Ó
,€CØ€EÙ‘�A“™˜1›Ó€DÙ
‘�1“‘r˜!“uÓ
€CÙ‘b˜“e™R ›UÓ#€IØ�)˜c˜T I :Ð.€Eà
€CàÐØ€Gò%ò"òð ñó ðòòòò+ò/ò
'ò òó>r   rþ   N) rt   Ú
__future__r   Úsympy.core.numbersr   Úsympy.polys.polyclassesr   Ú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   r|   r‰   rŽ   rÆ   rÇ   r   rþ   r^   r1   r   r   Ú<module>r      s¦   ðÙ å "Ý  Ý 'Ý 1Ý .Ý 0Ý =Ý -Ý ;Ý +Ý )ôX5�mô X5ôv%!�oô %!ôP )�ô  )÷FO1ñ O1ôdx8˜.¨$ô x8ñt "5Ó!6Ð 6€€Ôôz>˜N¨Eô z>ñz #8Ó"9Ð 9€ÐÕr   