U
    ZÊ¹j=J  ã                   @   sî   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„ deƒZG dd„ deƒZG dd„ deƒZG dd„ dƒZG dd„ deeƒZeƒ  Ze_G dd„ deeƒZeƒ  Ze_dS )zDomains of Gaussian type.é    )ÚI)ÚCoercionFailed)ÚZZ)ÚQQ)ÚAlgebraicField)ÚDomain)ÚDomainElement)ÚField)ÚRingc                       s   e Zd ZU dZeed< eed< dZd6dd„Ze‡ fdd	„ƒZ	d
d„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zedd„ ƒZdd„ ZeZdd„ Zd d!„ Zd"d#„ ZeZd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Zd2d3„ Z d4d5„ Z!‡  Z"S )7ÚGaussianElementz1Base class for elements of Gaussian type domains.ÚbaseÚ_parent)ÚxÚyr   c                 C   s   | j j}|  ||ƒ||ƒ¡S ©N)r   ÚconvertÚnew)Úclsr   r   Úconv© r   úb/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/polys/domains/gaussiandomains.pyÚ__new__   s    zGaussianElement.__new__c                    s   t ƒ  | ¡}||_||_|S )z0Create a new GaussianElement of the same domain.)Úsuperr   r   r   )r   r   r   Úobj©Ú	__class__r   r   r      s    zGaussianElement.newc                 C   s   | j S )z4The domain that this is an element of (ZZ_I or QQ_I))r   ©Úselfr   r   r   Úparent!   s    zGaussianElement.parentc                 C   s   t | j| jfƒS r   )Úhashr   r   r   r   r   r   Ú__hash__%   s    zGaussianElement.__hash__c                 C   s,   t || jƒr$| j|jko"| j|jkS tS d S r   )Ú
isinstancer   r   r   ÚNotImplemented©r   Úotherr   r   r   Ú__eq__(   s    zGaussianElement.__eq__c                 C   s&   t |tƒstS | j| jg|j|jgk S r   )r!   r   r"   r   r   r#   r   r   r   Ú__lt__.   s    
zGaussianElement.__lt__c                 C   s   | S r   r   r   r   r   r   Ú__pos__3   s    zGaussianElement.__pos__c                 C   s   |   | j | j ¡S r   ©r   r   r   r   r   r   r   Ú__neg__6   s    zGaussianElement.__neg__c                 C   s   d| j j| j| jf S )Nz
%s(%s, %s))r   Úrepr   r   r   r   r   r   Ú__repr__9   s    zGaussianElement.__repr__c                 C   s   t | j | ¡ƒS r   )Ústrr   Úto_sympyr   r   r   r   Ú__str__<   s    zGaussianElement.__str__c                 C   s>   t || ƒs2z| j |¡}W n tk
r0   Y dS X |j|jfS )N)NN)r!   r   r   r   r   r   )r   r$   r   r   r   Ú_get_xy?   s    
zGaussianElement._get_xyc                 C   s6   |   |¡\}}|d k	r.|  | j| | j| ¡S tS d S r   ©r/   r   r   r   r"   ©r   r$   r   r   r   r   r   Ú__add__H   s    zGaussianElement.__add__c                 C   s6   |   |¡\}}|d k	r.|  | j| | j| ¡S tS d S r   r0   r1   r   r   r   Ú__sub__Q   s    zGaussianElement.__sub__c                 C   s6   |   |¡\}}|d k	r.|  || j || j ¡S tS d S r   r0   r1   r   r   r   Ú__rsub__X   s    zGaussianElement.__rsub__c                 C   sJ   |   |¡\}}|d k	rB|  | j| | j|  | j| | j|  ¡S tS d S r   r0   r1   r   r   r   Ú__mul___   s    ,zGaussianElement.__mul__c                 C   s‚   |dkr|   dd¡S |dk r,d|  |  } }|dkr8| S | }|d rH| n| jj}|d }|r~||9 }|d rt||9 }|d }qX|S )Nr   é   é   )r   r   Úone)r   ÚexpZpow2Úprodr   r   r   Ú__pow__h   s    
zGaussianElement.__pow__c                 C   s   t | jƒpt | jƒS r   )Úboolr   r   r   r   r   r   Ú__bool__y   s    zGaussianElement.__bool__c                 C   sN   | j dkr| jdkrdS dS | j dk r8| jdk r4dS dS | jdkrFdS dS dS )zIReturn quadrant index 0-3.

        0 is included in quadrant 0.
        r   r6   r7   é   N)r   r   r   r   r   r   Úquadrant|   s
    

zGaussianElement.quadrantc                 C   s8   z| j  |¡}W n tk
r(   t Y S X | | ¡S d S r   )r   r   r   r"   Ú
__divmod__r#   r   r   r   Ú__rdivmod__ˆ   s
    
zGaussianElement.__rdivmod__c                 C   s6   zt  |¡}W n tk
r&   t Y S X | | ¡S d S r   )ÚQQ_Ir   r   r"   Ú__truediv__r#   r   r   r   Ú__rtruediv__�   s
    
zGaussianElement.__rtruediv__c                 C   s   |   |¡}|tkr|S |d S ©Nr   ©r@   r"   ©r   r$   Zqrr   r   r   Ú__floordiv__˜   s    
zGaussianElement.__floordiv__c                 C   s   |   |¡}|tkr|S |d S rE   ©rA   r"   rG   r   r   r   Ú__rfloordiv__œ   s    
zGaussianElement.__rfloordiv__c                 C   s   |   |¡}|tkr|S |d S ©Nr6   rF   rG   r   r   r   Ú__mod__    s    
zGaussianElement.__mod__c                 C   s   |   |¡}|tkr|S |d S rK   rI   rG   r   r   r   Ú__rmod__¤   s    
zGaussianElement.__rmod__)r   )#Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú__annotations__Ú	__slots__r   Úclassmethodr   r   r    r%   r&   r'   r)   r+   r.   r/   r2   Ú__radd__r3   r4   r5   Ú__rmul__r;   r=   r?   rA   rD   rH   rJ   rL   rM   Ú__classcell__r   r   r   r   r      s@   


r   c                   @   s$   e Zd ZdZeZdd„ Zdd„ ZdS )Ú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                 C   s   t  | ¡| S )úReturn a Gaussian rational.)rB   r   r#   r   r   r   rC   µ   s    zGaussianInteger.__truediv__c           
      C   sª   |st d | ¡ƒ‚|  |¡\}}|d kr,tS | j| | j|  | j | | j|   }}|| ||  }d| | d|  }d| | d|  }t||ƒ}	|	| |	|  fS )Nzdivmod({}, 0)r7   )ÚZeroDivisionErrorÚformatr/   r"   r   r   rX   )
r   r$   r   r   ÚaÚbÚcZqxZqyÚqr   r   r   r@   ¹   s    ,
zGaussianInteger.__divmod__N)rN   rO   rP   rQ   r   r   rC   r@   r   r   r   r   rX   ©   s   	rX   c                   @   s$   e Zd ZdZeZdd„ Zdd„ ZdS )Ú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                 C   sp   |st d | ¡ƒ‚|  |¡\}}|dkr,tS || ||  }t| j| | j|  | | j | | j|  | ƒS )rY   z{} / 0N)rZ   r[   r/   r"   r`   r   r   )r   r$   r   r   r^   r   r   r   rC   Ý   s    ÿzGaussianRational.__truediv__c                 C   sP   z| j  |¡}W n tk
r(   t Y S X |s>td | ¡ƒ‚n| | tjfS d S )Nz{} % 0)r   r   r   r"   rZ   r[   rB   Úzeror#   r   r   r   r@   é   s    
zGaussianRational.__divmod__N)rN   rO   rP   rQ   r   r   rC   r@   r   r   r   r   r`   Ñ   s   	r`   c                   @   sœ   e Zd ZdZdZdZdZdZdZdd„ Z	dd„ Z
dd	„ Zd
d„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ ZdS )"ÚGaussianDomainz Base class for Gaussian domains.NTc                 C   s    | j j}||jƒt||jƒ  S )z!Convert ``a`` to a SymPy object. )Údomr-   r   r   r   )r   r\   r   r   r   r   r-   þ   s    zGaussianDomain.to_sympyc                 C   sf   |  ¡ \}}| j |¡}|s(|  |d¡S | ¡ \}}| j |¡}|tkrT|  ||¡S td |¡ƒ‚dS )z)Convert a SymPy object to ``self.dtype``.r   z{} is not GaussianN)Zas_coeff_Addrc   Ú
from_sympyr   Zas_coeff_Mulr   r   r[   )r   r\   Úrr]   r   r   r   r   r   rd     s    zGaussianDomain.from_sympyc                 G   s
   | j |Ž S )z$Inject generators into this domain. )Z	poly_ring)r   Zgensr   r   r   Úinject  s    zGaussianDomain.injectc                 C   s   | j | ¡   }|S r   )Úunitsr?   )r   ÚdÚunitr   r   r   Úcanonical_unit  s    zGaussianDomain.canonical_unitc                 C   s   dS ©z/Returns ``False`` for any ``GaussianElement``. Fr   ©r   Úelementr   r   r   Úis_negative  s    zGaussianDomain.is_negativec                 C   s   dS rk   r   rl   r   r   r   Úis_positive  s    zGaussianDomain.is_positivec                 C   s   dS rk   r   rl   r   r   r   Úis_nonnegative   s    zGaussianDomain.is_nonnegativec                 C   s   dS rk   r   rl   r   r   r   Úis_nonpositive$  s    zGaussianDomain.is_nonpositivec                 C   s   | |ƒS )z%Convert a GMPY mpz to ``self.dtype``.r   ©ZK1r\   ZK0r   r   r   Úfrom_ZZ_gmpy(  s    zGaussianDomain.from_ZZ_gmpyc                 C   s   | |ƒS ©z.Convert a ZZ_python element to ``self.dtype``.r   rr   r   r   r   Úfrom_ZZ,  s    zGaussianDomain.from_ZZc                 C   s   | |ƒS rt   r   rr   r   r   r   Úfrom_ZZ_python0  s    zGaussianDomain.from_ZZ_pythonc                 C   s   | |ƒS ©z%Convert a GMPY mpq to ``self.dtype``.r   rr   r   r   r   Úfrom_QQ4  s    zGaussianDomain.from_QQc                 C   s   | |ƒS rw   r   rr   r   r   r   Úfrom_QQ_gmpy8  s    zGaussianDomain.from_QQ_gmpyc                 C   s   | |ƒS )z.Convert a QQ_python element to ``self.dtype``.r   rr   r   r   r   Úfrom_QQ_python<  s    zGaussianDomain.from_QQ_pythonc                 C   s$   |j jd tkr |  | |¡¡S dS )z9Convert an element from ZZ<I> or QQ<I> to ``self.dtype``.r   N)ÚextÚargsr   rd   r-   rr   r   r   r   Úfrom_AlgebraicField@  s    z"GaussianDomain.from_AlgebraicField)rN   rO   rP   rQ   rc   Zis_NumericalZis_ExactZhas_assoc_RingZhas_assoc_Fieldr-   rd   rf   rj   rn   ro   rp   rq   rs   ru   rv   rx   ry   rz   r}   r   r   r   r   rb   ô   s*   rb   c                   @   sÎ   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d„ Zdd	„ Zd
d„ Zedd„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )Ú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   r6   ÚZZ_ITc                 C   s   dS )zFor constructing ZZ_I.Nr   r   r   r   r   Ú__init__¶  s    zGaussianIntegerRing.__init__c                 C   s   t |tƒrdS tS dS ©z0Returns ``True`` if two domains are equivalent. TN)r!   r~   r"   r#   r   r   r   r%   ¹  s    
zGaussianIntegerRing.__eq__c                 C   s   t dƒS )úCompute hash code of ``self``. r   ©r   r   r   r   r   r    À  s    zGaussianIntegerRing.__hash__c                 C   s   dS ©NTr   r   r   r   r   Úhas_CharacteristicZeroÄ  s    z*GaussianIntegerRing.has_CharacteristicZeroc                 C   s   dS rE   r   r   r   r   r   ÚcharacteristicÈ  s    z"GaussianIntegerRing.characteristicc                 C   s   | S ©z)Returns a ring associated with ``self``. r   r   r   r   r   Úget_ringË  s    zGaussianIntegerRing.get_ringc                 C   s   t S ©z*Returns a field associated with ``self``. )rB   r   r   r   r   Ú	get_fieldÏ  s    zGaussianIntegerRing.get_fieldc                    s:   |   |¡‰ |ˆ 9 }t‡ fdd„|D ƒƒ}|r6|f| S |S )z€Return first quadrant element associated with ``d``.

        Also multiply the other arguments by the same power of i.
        c                 3   s   | ]}|ˆ  V  qd S r   r   )Ú.0r\   ©ri   r   r   Ú	<genexpr>Ú  s     z0GaussianIntegerRing.normalize.<locals>.<genexpr>)rj   Útuple)r   rh   r|   r   rŒ   r   Ú	normalizeÓ  s    
zGaussianIntegerRing.normalizec                 C   s   |r|||  }}q |   |¡S )z-Greatest common divisor of a and b over ZZ_I.)r�   ©r   r\   r]   r   r   r   ÚgcdÝ  s    zGaussianIntegerRing.gcdc                 C   s   || |   ||¡ S )z+Least common multiple of a and b over ZZ_I.)r‘   r�   r   r   r   Úlcmã  s    zGaussianIntegerRing.lcmc                 C   s   |S )zConvert a ZZ_I element to ZZ_I.r   rr   r   r   r   Úfrom_GaussianIntegerRingç  s    z,GaussianIntegerRing.from_GaussianIntegerRingc                 C   s   |   t |j¡t |j¡¡S )zConvert a QQ_I element to ZZ_I.)r   r   r   r   r   rr   r   r   r   Úfrom_GaussianRationalFieldë  s    z.GaussianIntegerRing.from_GaussianRationalFieldN)rN   rO   rP   rQ   r   rc   rX   Údtypera   r8   Ú	imag_unitrg   r*   Zis_GaussianRingZis_ZZ_Ir€   r%   r    Úpropertyr…   r†   rˆ   rŠ   r�   r‘   r’   r“   r”   r   r   r   r   r~   F  s.   c

r~   c                   @   sÖ   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d„ Zdd	„ Zd
d„ Zedd„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd S )!Ú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   r6   rB   Tc                 C   s   dS )zFor constructing QQ_I.Nr   r   r   r   r   r€   s  s    zGaussianRationalField.__init__c                 C   s   t |tƒrdS tS dS r�   )r!   r˜   r"   r#   r   r   r   r%   v  s    
zGaussianRationalField.__eq__c                 C   s   t dƒS )r‚   rB   rƒ   r   r   r   r   r    }  s    zGaussianRationalField.__hash__c                 C   s   dS r„   r   r   r   r   r   r…   �  s    z,GaussianRationalField.has_CharacteristicZeroc                 C   s   dS rE   r   r   r   r   r   r†   …  s    z$GaussianRationalField.characteristicc                 C   s   t S r‡   )r   r   r   r   r   rˆ   ˆ  s    zGaussianRationalField.get_ringc                 C   s   | S r‰   r   r   r   r   r   rŠ   Œ  s    zGaussianRationalField.get_fieldc                 C   s   t | jtƒS )z0Get equivalent domain as an ``AlgebraicField``. )r   rc   r   r   r   r   r   Úas_AlgebraicField�  s    z'GaussianRationalField.as_AlgebraicFieldc                 C   s   |   ¡ }| ||  |¡ ¡S )zGet the numerator of ``a``.)rˆ   r   Údenom)r   r\   r   r   r   r   Únumer”  s    zGaussianRationalField.numerc                 C   s@   | j  ¡ }| j }|  ¡ }| | |j¡| |j¡¡}|||jƒS )zGet the denominator of ``a``.)rc   rˆ   r’   rš   r   r   ra   )r   r\   r   r   r   Zdenom_ZZr   r   r   rš   ™  s
    
zGaussianRationalField.denomc                 C   s   |   |j|j¡S )zConvert a ZZ_I element to QQ_I.r(   rr   r   r   r   r“   ¡  s    z.GaussianRationalField.from_GaussianIntegerRingc                 C   s   |S )zConvert a QQ_I element to QQ_I.r   rr   r   r   r   r”   ¥  s    z0GaussianRationalField.from_GaussianRationalFieldc                 C   s   |   t |j¡t |j¡¡S )z'Convert a ComplexField element to QQ_I.)r   r   r   ÚrealÚimagrr   r   r   r   Úfrom_ComplexField©  s    z'GaussianRationalField.from_ComplexFieldN)rN   rO   rP   rQ   r   rc   r`   r•   ra   r8   r–   rg   r*   Zis_GaussianFieldZis_QQ_Ir€   r%   r    r—   r…   r†   rˆ   rŠ   r™   r›   rš   r“   r”   rž   r   r   r   r   r˜   ò  s0   t
r˜   N)rQ   Zsympy.core.numbersr   Zsympy.polys.polyerrorsr   Zsympy.polys.domains.integerringr   Z!sympy.polys.domains.rationalfieldr   Z"sympy.polys.domains.algebraicfieldr   Zsympy.polys.domains.domainr   Z!sympy.polys.domains.domainelementr   Zsympy.polys.domains.fieldr	   Zsympy.polys.domains.ringr
   r   rX   r`   rb   r~   r   r   r˜   rB   r   r   r   r   Ú<module>   s(    (#R * =