U
    ZÊ¹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mZ d
dlmZ d
dlmZmZ d
dlmZmZ dd„ ZG dd„ deƒZdd„ Zedd„ ƒZd$dd„Z dd„ Z!dd„ Z"dd„ Z#d d!„ Z$ed%d"d#„ƒZ%dS )&zPrime ideals in number fields. é    )ÚPoly)ÚFF)ÚQQ)ÚZZ)ÚDomainMatrix)ÚCoercionFailed)ÚIntegerPowerable)Úpublicé   )Ú	round_twoÚnilradical_mod_p)ÚStructureError)ÚModuleEndomorphismÚfind_min_poly)Úcoeff_searchÚsupplement_a_subspacec                 C   sH   d}d}|   ¡ sd}n|  ¡ s$d}n|  ¡ s0d}|dk	rDt|| ƒ‚dS )a  
    Several functions in this module accept an argument which is to be a
    :py:class:`~.Submodule` representing the maximal order in a number field,
    such as returned by the :py:func:`~sympy.polys.numberfields.basis.round_two`
    algorithm.

    We do not attempt to check that the given ``Submodule`` actually represents
    a maximal order, but we do check a basic set of formal conditions that the
    ``Submodule`` must satisfy, at a minimum. The purpose is to catch an
    obviously ill-formed argument.
    z4The submodule representing the maximal order should Nz'be a direct submodule of a power basis.zhave 1 as its first generator.z<have square matrix, of maximal rank, in Hermite Normal Form.)Zis_power_basis_submoduleÚstarts_with_unityZis_sq_maxrank_HNFr   )Ú	submoduleÚprefixZcond© r   ú^/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/polys/numberfields/primes.pyÚ*_check_formal_conditions_for_maximal_order   s    r   c                   @   s    e Zd ZdZd$dd„Zdd„ Zedd„ ƒZd%d
d„Zdd„ Z	dd„ Z
dd„ Zdd„ ZeZdd„ ZeZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ ZdS )&Ú
PrimeIdealz8
    A prime ideal in a ring of algebraic integers.
    Nc                 C   sF   t |ƒ || _|| _|| _|| _d| _|dk	r2|n|  || ¡| _dS )aü  
        Parameters
        ==========

        ZK : :py:class:`~.Submodule`
            The maximal order where this ideal lives.
        p : int
            The rational prime this ideal divides.
        alpha : :py:class:`~.PowerBasisElement`
            Such that the ideal is equal to ``p*ZK + alpha*ZK``.
        f : int
            The inertia degree.
        e : int, ``None``, optional
            The ramification index, if already known. If ``None``, we will
            compute it here.

        N)r   ÚZKÚpÚalphaÚfÚ_test_factorÚ	valuationÚe)Úselfr   r   r   r   r   r   r   r   Ú__init__.   s    zPrimeIdeal.__init__c                 C   s.   | j rd| j› d�S d| j› d| j ¡ › d�S )Nú(ú)ú, )Úis_inertr   r   Úas_expr©r    r   r   r   Ú__str__H   s    zPrimeIdeal.__str__c                 C   s   | j | jjkS )zv
        Say whether the rational prime we divide is inert, i.e. stays prime in
        our ring of integers.
        )r   r   Únr'   r   r   r   r%   M   s    zPrimeIdeal.is_inertFc           	      C   sŽ   |p| j jjj}| j| j| j| jf\}}}}t|j	|d� 
¡ ƒ}|jdkr\d|› d|j› �}d|› d|› d�}|rv|S d|› d|› d	|› d
�S )a  
        Print a representation of this prime ideal.

        Examples
        ========

        >>> from sympy import cyclotomic_poly, QQ
        >>> from sympy.abc import x, zeta
        >>> T = cyclotomic_poly(7, x)
        >>> K = QQ.algebraic_field((T, zeta))
        >>> P = K.primes_above(11)
        >>> print(P[0].repr())
        [ (11, x**3 + 5*x**2 + 4*x - 1) e=1, f=3 ]
        >>> print(P[0].repr(field_gen=zeta))
        [ (11, zeta**3 + 5*zeta**2 + 4*zeta - 1) e=1, f=3 ]
        >>> print(P[0].repr(field_gen=zeta, just_gens=True))
        (11, zeta**3 + 5*zeta**2 + 4*zeta - 1)

        Parameters
        ==========

        field_gen : :py:class:`~.Symbol`, ``None``, optional (default=None)
            The symbol to use for the generator of the field. This will appear
            in our representation of ``self.alpha``. If ``None``, we use the
            variable of the defining polynomial of ``self.ZK``.
        just_gens : bool, optional (default=False)
            If ``True``, just print the "(p, alpha)" part, showing "just the
            generators" of the prime ideal. Otherwise, print a string of the
            form "[ (p, alpha) e=..., f=... ]", giving the ramification index
            and inertia degree, along with the generators.

        ©Úxr
   r"   z)/r$   r#   z[ z e=z, f=z ])r   ÚparentÚTÚgenr   r   r   r   ÚstrÚ	numeratorr&   Údenom)	r    Z	field_genZ	just_gensr   r   r   r   Z	alpha_repÚgensr   r   r   ÚreprU   s    !
zPrimeIdeal.reprc                 C   s   |   ¡ S ©N)r3   r'   r   r   r   Ú__repr__€   s    zPrimeIdeal.__repr__c                 C   s(   | j | j | j| j  }d|_d|_|S )aï  
        Represent this prime ideal as a :py:class:`~.Submodule`.

        Explanation
        ===========

        The :py:class:`~.PrimeIdeal` class serves to bundle information about
        a prime ideal, such as its inertia degree, ramification index, and
        two-generator representation, as well as to offer helpful methods like
        :py:meth:`~.PrimeIdeal.valuation` and
        :py:meth:`~.PrimeIdeal.test_factor`.

        However, in order to be added and multiplied by other ideals or
        rational numbers, it must first be converted into a
        :py:class:`~.Submodule`, which is a class that supports these
        operations.

        In many cases, the user need not perform this conversion deliberately,
        since it is automatically performed by the arithmetic operator methods
        :py:meth:`~.PrimeIdeal.__add__` and :py:meth:`~.PrimeIdeal.__mul__`.

        Raising a :py:class:`~.PrimeIdeal` to a non-negative integer power is
        also supported.

        Examples
        ========

        >>> from sympy import Poly, cyclotomic_poly, prime_decomp
        >>> T = Poly(cyclotomic_poly(7))
        >>> P0 = prime_decomp(7, T)[0]
        >>> print(P0**6 == 7*P0.ZK)
        True

        Note that, on both sides of the equation above, we had a
        :py:class:`~.Submodule`. In the next equation we recall that adding
        ideals yields their GCD. This time, we need a deliberate conversion
        to :py:class:`~.Submodule` on the right:

        >>> print(P0 + 7*P0.ZK == P0.as_submodule())
        True

        Returns
        =======

        :py:class:`~.Submodule`
            Will be equal to ``self.p * self.ZK + self.alpha * self.ZK``.

        See Also
        ========

        __add__
        __mul__

        FT)r   r   r   Z_starts_with_unityZ_is_sq_maxrank_HNF)r    ÚMr   r   r   Úas_submoduleƒ   s    7zPrimeIdeal.as_submodulec                 C   s   t |tƒr|  ¡ | ¡ kS tS r4   )Ú
isinstancer   r7   ÚNotImplemented©r    Úotherr   r   r   Ú__eq__À   s    
zPrimeIdeal.__eq__c                 C   s   |   ¡ | S )z¤
        Convert to a :py:class:`~.Submodule` and add to another
        :py:class:`~.Submodule`.

        See Also
        ========

        as_submodule

        ©r7   r:   r   r   r   Ú__add__Å   s    zPrimeIdeal.__add__c                 C   s   |   ¡ | S )z¾
        Convert to a :py:class:`~.Submodule` and multiply by another
        :py:class:`~.Submodule` or a rational number.

        See Also
        ========

        as_submodule

        r=   r:   r   r   r   Ú__mul__Ô   s    zPrimeIdeal.__mul__c                 C   s   | j S r4   )r   r'   r   r   r   Ú_zeroth_powerã   s    zPrimeIdeal._zeroth_powerc                 C   s   | S r4   r   r'   r   r   r   Ú_first_poweræ   s    zPrimeIdeal._first_powerc                 C   s&   | j dkr t| j| jg| jƒ| _ | j S )aO  
        Compute a test factor for this prime ideal.

        Explanation
        ===========

        Write $\mathfrak{p}$ for this prime ideal, $p$ for the rational prime
        it divides. Then, for computing $\mathfrak{p}$-adic valuations it is
        useful to have a number $\beta \in \mathbb{Z}_K$ such that
        $p/\mathfrak{p} = p \mathbb{Z}_K + \beta \mathbb{Z}_K$.

        Essentially, this is the same as the number $\Psi$ (or the "reagent")
        from Kummer's 1847 paper (*Ueber die Zerlegung...*, Crelle vol. 35) in
        which ideal divisors were invented.
        N)r   Ú_compute_test_factorr   r   r   r'   r   r   r   Útest_factoré   s    
zPrimeIdeal.test_factorc                 C   s
   t || ƒS )zõ
        Compute the $\mathfrak{p}$-adic valuation of integral ideal I at this
        prime ideal.

        Parameters
        ==========

        I : :py:class:`~.Submodule`

        See Also
        ========

        prime_valuation

        )Úprime_valuation)r    ÚIr   r   r   r   ý   s    zPrimeIdeal.valuationc                 C   s   |   ¡  |¡S )aÐ  
        Reduce a :py:class:`~.PowerBasisElement` to a "small representative"
        modulo this prime ideal.

        Parameters
        ==========

        elt : :py:class:`~.PowerBasisElement`
            The element to be reduced.

        Returns
        =======

        :py:class:`~.PowerBasisElement`
            The reduced element.

        See Also
        ========

        reduce_ANP
        reduce_alg_num
        .Submodule.reduce_element

        )r7   Úreduce_element)r    Úeltr   r   r   rF     s    zPrimeIdeal.reduce_elementc                 C   s    | j j |¡}|  |¡}| ¡ S )a«  
        Reduce an :py:class:`~.ANP` to a "small representative" modulo this
        prime ideal.

        Parameters
        ==========

        elt : :py:class:`~.ANP`
            The element to be reduced.

        Returns
        =======

        :py:class:`~.ANP`
            The reduced element.

        See Also
        ========

        reduce_element
        reduce_alg_num
        .Submodule.reduce_element

        )r   r,   Zelement_from_ANPrF   Zto_ANP©r    ÚarG   Úredr   r   r   Ú
reduce_ANP*  s    
zPrimeIdeal.reduce_ANPc                 C   s0   | j j |¡}|  |¡}| tt|j ¡ ƒƒ¡S )aË  
        Reduce an :py:class:`~.AlgebraicNumber` to a "small representative"
        modulo this prime ideal.

        Parameters
        ==========

        elt : :py:class:`~.AlgebraicNumber`
            The element to be reduced.

        Returns
        =======

        :py:class:`~.AlgebraicNumber`
            The reduced element.

        See Also
        ========

        reduce_element
        reduce_ANP
        .Submodule.reduce_element

        )	r   r,   Zelement_from_alg_numrF   Zfield_elementÚlistÚreversedZQQ_colÚflatrH   r   r   r   Úreduce_alg_numG  s    
zPrimeIdeal.reduce_alg_num)N)NF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r!   r(   Úpropertyr%   r3   r5   r7   r<   r>   Ú__radd__r?   Ú__rmul__r@   rA   rC   r   rF   rK   rO   r   r   r   r   r   )   s(   


+=r   c                    sx   t |ƒ | ¡ ‰ ‡ ‡fdd„|D ƒ}t d|jftˆƒ¡j|Ž }| ¡ ddd…f  ¡ }|j	|j
| t¡ |jd�}|S )aÝ  
    Compute the test factor for a :py:class:`~.PrimeIdeal` $\mathfrak{p}$.

    Parameters
    ==========

    p : int
        The rational prime $\mathfrak{p}$ divides

    gens : list of :py:class:`PowerBasisElement`
        A complete set of generators for $\mathfrak{p}$ over *ZK*, EXCEPT that
        an element equivalent to rational *p* can and should be omitted (since
        it has no effect except to waste time).

    ZK : :py:class:`~.Submodule`
        The maximal order where the prime ideal $\mathfrak{p}$ lives.

    Returns
    =======

    :py:class:`~.PowerBasisElement`

    References
    ==========

    .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*
    (See Proposition 4.8.15.)

    c                    s   g | ]}ˆ   |¡jˆd �‘qS )©Úmodulus)Zinner_endomorphismÚmatrix©Ú.0Úg©ÚEr   r   r   Ú
<listcomp>…  s     z(_compute_test_factor.<locals>.<listcomp>r   N©r1   )r   Zendomorphism_ringr   Zzerosr)   r   ZvstackZ	nullspaceZ	transposer,   rY   Ú
convert_tor   r1   )r   r2   r   ZmatricesÚBr+   Úbetar   r]   r   rB   e  s    rB   c                 C   sh  |j |j }}|j|j|j  }}}| t¡ ¡ | j | | j }| t¡}| 	¡ }|| dkrddS | 
¡ }	|| | 	¡  }
|
| dk}d}|| }t|ƒD ]R}|j|dd…|f |d�}||	9 }| |¡ ¡ }t|ƒD ]}|| |||f< qØqœ||d |d f j| dk�r�qd|| }|�rPz| t¡}W n tk
�rL   Y �qdY nX n
| t¡}|d7 }qŒ|S )aú  
    Compute the *P*-adic valuation for an integral ideal *I*.

    Examples
    ========

    >>> from sympy import QQ
    >>> from sympy.polys.numberfields import prime_valuation
    >>> K = QQ.cyclotomic_field(5)
    >>> P = K.primes_above(5)
    >>> ZK = K.maximal_order()
    >>> print(prime_valuation(25*ZK, P[0]))
    8

    Parameters
    ==========

    I : :py:class:`~.Submodule`
        An integral ideal whose valuation is desired.

    P : :py:class:`~.PrimeIdeal`
        The prime at which to compute the valuation.

    Returns
    =======

    int

    See Also
    ========

    .PrimeIdeal.valuation

    References
    ==========

    .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*
       (See Algorithm 4.8.17.)

    r   Nr`   r
   )r   r   r)   rY   r1   ra   r   Úinvr   ÚdetrC   Úranger,   Z	representrN   Úelementr   )rE   ÚPr   r   r)   ÚWÚdÚAÚDrc   r   Zneed_complete_testÚvÚjÚcÚir   r   r   rD   “  s:    *
 

rD   Nc                    sä   t |ƒ |j}|j}t‡ fdd„| D ƒƒr2| ¡ S |dkr`|dk	rLˆ | }nt| | ¡j ¡ ƒ}| 	¡ }‡ fdd„|dd… D ƒ}|| 7 }t
t|ƒdƒ}	|	D ]B}
tdd„ t|
|ƒD ƒƒ}| |¡| }|ˆ  dkrœ|ˆ    S qœdS )	a  
    Given a set of *ZK*-generators of a prime ideal, compute a set of just two
    *ZK*-generators for the same ideal, one of which is *p* itself.

    Parameters
    ==========

    gens : list of :py:class:`PowerBasisElement`
        Generators for the prime ideal over *ZK*, the ring of integers of the
        field $K$.

    ZK : :py:class:`~.Submodule`
        The maximal order in $K$.

    p : int
        The rational prime divided by the prime ideal.

    f : int, optional
        The inertia degree of the prime ideal, if known.

    Np : int, optional
        The norm $p^f$ of the prime ideal, if known.
        NOTE: There is no reason to supply both *f* and *Np*. Either one will
        save us from having to compute the norm *Np* ourselves. If both are known,
        *Np* is preferred since it saves one exponentiation.

    Returns
    =======

    :py:class:`~.PowerBasisElement` representing a single algebraic integer
    alpha such that the prime ideal is equal to ``p*ZK + alpha*ZK``.

    References
    ==========

    .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*
    (See Algorithm 4.7.10.)

    c                 3   s   | ]}|ˆ    d ¡V  qdS )r   N)ÚequivrZ   ©r   r   r   Ú	<genexpr>  s     z_two_elt_rep.<locals>.<genexpr>Nc                    s   g | ]}ˆ | ‘qS r   r   ©r[   Úomrr   r   r   r_   #  s     z _two_elt_rep.<locals>.<listcomp>r
   c                 s   s   | ]\}}|| V  qd S r4   r   )r[   ÚciZbetair   r   r   rs   '  s     r   )r   r,   r-   ÚallÚzeroÚabsZsubmodule_from_gensrY   re   Zbasis_element_pullbacksr   ÚlenÚsumÚzipZnorm)r2   r   r   r   ZNpZpbr-   Úomegarc   Úsearchro   r   r)   r   rr   r   Ú_two_elt_repì  s$    (
r   c                    sj   ˆ j j}t|ˆd�}| ¡ \}}t|ƒdkrV|d d dkrVtˆ ˆˆ j  ¡ ˆ jdƒgS ‡ ‡fdd„|D ƒS )a?  
    Compute the decomposition of rational prime *p* in the ring of integers
    *ZK* (given as a :py:class:`~.Submodule`), in the "easy case", i.e. the
    case where *p* does not divide the index of $\theta$ in *ZK*, where
    $\theta$ is the generator of the ``PowerBasis`` of which *ZK* is a
    ``Submodule``.
    rW   r
   r   c                    s4   g | ],\}}t ˆ ˆˆ j t|td �¡| ¡ |ƒ‘qS ©©Údomain)r   r,   Zelement_from_polyr   r   Zdegree)r[   Útr   ©r   r   r   r   r_   >  s   ý þz+_prime_decomp_easy_case.<locals>.<listcomp>)r,   r-   r   Úfactor_listrz   r   rx   r)   )r   r   r-   ZT_barÚlcÚflr   r„   r   Ú_prime_decomp_easy_case1  s    ýrˆ   c           
         s¸   | j }|j\}}|dkr&| |t¡}n| | |t¡dd…df ¡}|jd |k rjt| tˆ ƒ¡ƒ t¡}| |¡}| 	¡  | 
|¡}t|‡ fdd„ƒ}|jˆ d�}	|	 ¡ s°t‚|	|fS )a+  
    Parameters
    ==========

    I : :py:class:`~.Module`
        An ideal of ``ZK/pZK``.
    p : int
        The rational prime being factored.
    ZK : :py:class:`~.Submodule`
        The maximal order.

    Returns
    =======

    Pair ``(N, G)``, where:

        ``N`` is a :py:class:`~.Module` representing the kernel of the map
        ``a |--> a**p - a`` on ``(O/pO)/I``, guaranteed to be a module with
        unity.

        ``G`` is a :py:class:`~.Module` representing a basis for the separable
        algebra ``A = O/I`` (see Cohen).

    r   Nr
   c                    s   | ˆ  |  S r4   r   r*   rr   r   r   Ú<lambda>s  ó    z._prime_decomp_compute_kernel.<locals>.<lambda>rW   )rY   ÚshapeÚeyer   Úhstackr   ra   r   Úsubmodule_from_matrixZcompute_mult_tabZdiscard_beforer   Zkernelr   ÚAssertionError)
rE   r   r   ri   r)   Úrrb   ÚGÚphiÚNr   rr   r   Ú_prime_decomp_compute_kernelD  s    


r”   c                    s\   | j j\}}|| }ˆj | j  ‰ ‡ ‡fdd„tˆ jd ƒD ƒ}t|ˆ||d�}tˆ|||ƒS )aµ  
    We have reached the case where we have a maximal (hence prime) ideal *I*,
    which we know because the quotient ``O/I`` is a field.

    Parameters
    ==========

    I : :py:class:`~.Module`
        An ideal of ``O/pO``.
    p : int
        The rational prime being factored.
    ZK : :py:class:`~.Submodule`
        The maximal order.

    Returns
    =======

    :py:class:`~.PrimeIdeal` instance representing this prime

    c                    s(   g | ] }ˆj ˆ d d …|f ˆjd�‘qS )Nr`   )r,   r1   )r[   rn   ©r‘   r   r   r   r_   ‘  s     z/_prime_decomp_maximal_ideal.<locals>.<listcomp>r
   )r   )rY   r‹   rf   r   r   )rE   r   r   Úmr)   r   r2   r   r   r•   r   Ú_prime_decomp_maximal_idealy  s    r—   c                    sT  | j |kr|j |kr|j |ks"t‚|dƒ ¡ }|j|ks<t‚g ‰t|tˆƒˆd�}| ¡ \}}|d d }	| |	¡}
|	 |
¡\}}}|dks�t‚t	t
t||	 td�j ¡ ƒƒ‰ t‡ ‡fdd„ttˆ ƒƒD ƒƒ}d| }||g}g }|D ]h}| ¡ ‰ˆj|k�st‚| j tˆƒ¡j‡‡fdd„| ¡ D ƒŽ }| ¡  t¡}| |¡}| |¡ qæ|S )	zñ
    Perform the step in the prime decomposition algorithm where we have determined
    the quotient ``ZK/I`` is _not_ a field, and we want to perform a non-trivial
    factorization of *I* by locating an idempotent element of ``ZK/I``.
    r
   )Zpowersr   r�   c                 3   s   | ]}ˆ | ˆ|  V  qd S r4   r   )r[   rp   )r^   Úalpha_powersr   r   rs   °  s     z,_prime_decomp_split_ideal.<locals>.<genexpr>c                    s    g | ]}ˆ | j tˆƒd �‘qS r€   )Úcolumnr   rt   )r   r   r   r   r_   ·  s    z-_prime_decomp_split_ideal.<locals>.<listcomp>)r,   r�   Z	to_parentÚmoduler   r   r…   ZquoZgcdexrL   rM   r   r   ÚrepZto_listr{   rf   rz   rY   ra   r�   Zbasis_elementsZcolumnspacerŽ   Úappend)rE   r   r“   r‘   r   r   r–   r†   r‡   Úm1Úm2ÚUÚVr\   Zeps1Zeps2ZidempsZfactorsÚepsrl   ri   ÚHr   )r^   r˜   r   r   r   Ú_prime_decomp_split_ideal–  s2    "
 ÿ
r£   c                 C   s  |dkr|dkrt dƒ‚|dk	r(t|ƒ |dkr8|jj}i }|dksL|dkr\t||d�\}}| ¡ }|| }||  dkr‚t| |ƒS |p˜| | ¡p˜t|| ƒ}|g}g }	|�r| 	¡ }
t
|
| |ƒ\}}|jdkrät|
| |ƒ}|	 |¡ q¤t|
| |||ƒ\}}| ||g¡ q¤|	S )a¬  
    Compute the decomposition of rational prime *p* in a number field.

    Explanation
    ===========

    Ordinarily this should be accessed through the
    :py:meth:`~.AlgebraicField.primes_above` method of an
    :py:class:`~.AlgebraicField`.

    Examples
    ========

    >>> from sympy import Poly, QQ
    >>> from sympy.abc import x, theta
    >>> T = Poly(x ** 3 + x ** 2 - 2 * x + 8)
    >>> K = QQ.algebraic_field((T, theta))
    >>> print(K.primes_above(2))
    [[ (2, x**2 + 1) e=1, f=1 ], [ (2, (x**2 + 3*x + 2)/2) e=1, f=1 ],
     [ (2, (3*x**2 + 3*x)/2) e=1, f=1 ]]

    Parameters
    ==========

    p : int
        The rational prime whose decomposition is desired.

    T : :py:class:`~.Poly`, optional
        Monic irreducible polynomial defining the number field $K$ in which to
        factor. NOTE: at least one of *T* or *ZK* must be provided.

    ZK : :py:class:`~.Submodule`, optional
        The maximal order for $K$, if already known.
        NOTE: at least one of *T* or *ZK* must be provided.

    dK : int, optional
        The discriminant of the field $K$, if already known.

    radical : :py:class:`~.Submodule`, optional
        The nilradical mod *p* in the integers of $K$, if already known.

    Returns
    =======

    List of :py:class:`~.PrimeIdeal` instances.

    References
    ==========

    .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*
       (See Algorithm 6.2.9.)

    Nz)At least one of T or ZK must be provided.)Úradicalsr   r
   )Ú
ValueErrorr   r,   r-   r   Zdiscriminantrˆ   Úgetr   Úpopr”   r)   r—   rœ   r£   Úextend)r   r-   r   ZdKÚradicalr¤   ZdTZ	f_squaredÚstackZprimesrE   r“   r‘   rh   ZI1ZI2r   r   r   Úprime_decompÀ  s2    7

r«   )NN)NNNN)&rS   Zsympy.polys.polytoolsr   Zsympy.polys.domains.finitefieldr   Z!sympy.polys.domains.rationalfieldr   Zsympy.polys.domains.integerringr   Z!sympy.polys.matrices.domainmatrixr   Zsympy.polys.polyerrorsr   Zsympy.polys.polyutilsr   Zsympy.utilities.decoratorr	   Zbasisr   r   Ú
exceptionsr   Úmodulesr   r   Z	utilitiesr   r   r   r   rB   rD   r   rˆ   r”   r—   r£   r«   r   r   r   r   Ú<module>   s4     >.
X
E5*