
    sg=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       V/var/www/html/venv/lib/python3.12/site-packages/sympy/polys/domains/gaussiandomains.py__new__zGaussianElement.__new__   s*    xxwwtAw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&     goc"
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    TVVTVV$%%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;    eT^^,66UWW$:577)::!!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!!577EGG"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    xx$&&))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 ww " "!"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=88DFFQJ
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=88AJDFF
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=88DFF1Htvvax/DFF1H1D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88Aq>!7$#D!8KQwtDLL$4$4	DLDQwAIC	 
 r   c                 Z    t        | j                        xs t        | j                        S r   )boolr   r   r    s    r   __bool__zGaussianElement.__bool__y   s    DFF|+tDFF|+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    
 66A:
1))VVaZ
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    	*LL((/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?    	+LL'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4r!u4r   c                 B    | j                  |      }|t        u r|S |d   S r`   rZ   r(   rb   s      r   __rfloordiv__zGaussianElement.__rfloordiv__   (    e$>)r4r!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)GaussianIntegerzGaussian 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!! vvax$&&("TVVGAIq$81aC!A#I cAg1Q3cAg1Q3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    #HOOD$9::||E"19!!aC!A#IDFF1H!4a 7"&&&TVVAX!5q 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^    	"LL((/E #HOOD$9:::tyy((  	"!!	"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    xx  ACCy1T!##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HH"88Aq>!~~1HH"688Aq>! !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    zz1::<-(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    66;;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 )zReturn 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     *QtV*s   )r   tuple)r!   r   r   r   s      @r   	normalizezGaussianIntegerRing.normalize  sA    
 ""1%	T	*T**"td{))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!eqA ~~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$((1a.((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+    vvbjjorzz!##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eRU#I)cTI:.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    dhh**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    XX XX}}266("((133-!##7Hbgg&&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    vvacc133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-    vvbjj("**QVV*<==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eRU#I)cTI:.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5m X5v%!o %!P )  )FO1 O1dg8.$ g8R "5!6 6y>NE y>x #8"9 9r   