§
    OŠtjiå  ã                   ó6  — 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
mZmZmZ d dlmZ d dlmZ d dlZd	„ Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd*d„Zd„ Zd„ Z d„ Z!d„ Z"d„ Z#d„ Z$d„ Z%d„ Z&d„ Z'd+d„Z(d „ Z)d!„ Z*d"„ Z+d#„ Z,d$„ Z-d%„ Z.d&„ Z/d'„ Z0d(„ Z1d)„ Z2dS ),é    )ÚDummy)Ú	nextprime©Úcrt)ÚPolynomialRing)Úgf_gcdÚgf_from_dictÚgf_gcdexÚgf_divÚgf_lcm)ÚModularGCDFailed)ÚsqrtNc                 ó   — | j         }| s|s|j        |j        |j        fS | s5|j        |j        j        k     r| |j        |j         fS ||j        |j        fS |s5| j        |j        j        k     r|  |j         |j        fS | |j        |j        fS dS )zn
    Compute the GCD of two polynomials in trivial cases, i.e. when one
    or both polynomials are zero.
    N)ÚringÚzeroÚLCÚdomainÚone)ÚfÚgr   s      úT/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/sympy/polys/modulargcd.pyÚ_trivial_gcdr      s²   € ð
 Œ6€Dàð *�ð *ØŒy˜$œ) T¤YÐ.Ð.Øð 	*ØŒ4�$”+Ô"Ò"Ð"Ø�2�t”y 4¤8 )Ð+Ð+à�d”i ¤Ð)Ð)Øð *ØŒ4�$”+Ô"Ò"Ð"Ø�2˜œ�y $¤)Ð+Ð+à�d”h ¤	Ð)Ð)Øˆ4ó    c                 óÜ  — | j         j        }|rž| }|                     ¦   «         }|                     |j        |¦  «        }	 |                     ¦   «         }||k     rnK||                     ||z
  f¦  «                             ||j        z  ¦  «        z
                       |¦  «        }Œf|} |}|°ž|                      |                     | j        |¦  «        ¦  «                             |¦  «        S )zM
    Compute the GCD of two univariate polynomials in `\mathbb{Z}_p[x]`.
    )r   r   ÚdegreeÚinvertr   Ú	mul_monomÚ
mul_groundÚtrunc_ground)ÚfpÚgpÚpÚdomÚremÚdegÚlcinvÚdegrems           r   Ú_gf_gcdr(   #   sè   € ð Œ'Œ.€Cà
ð ØˆØ�iŠi‰kŒkˆØ—
’
˜2œ5 !Ñ$Ô$ˆð	cØ—Z’Z‘\”\ˆFØ˜Š|ˆ|ØØ˜Ÿš v°¡| oÑ6Ô6×AÒAÀ%È#Ì&Á.ÑQÔQÑQ×_Ò_Ð`aÑbÔbˆCð		cð ˆØˆð ð ð �=Š=˜Ÿš B¤E¨1Ñ-Ô-Ñ.Ô.×;Ò;¸AÑ>Ô>Ð>r   c                 ó\  — | j         j                             | j        |j        ¦  «        }d}t	          |¦  «        }||z  dk    rt	          |¦  «        }||z  dk    °|                      |¦  «        }|                     |¦  «        }t          |||¦  «        }|                     ¦   «         }|S )aø  
    Compute an upper bound for the degree of the GCD of two univariate
    integer polynomials `f` and `g`.

    The function chooses a suitable prime `p` and computes the GCD of
    `f` and `g` in `\mathbb{Z}_p[x]`. The choice of `p` guarantees that
    the degree in `\mathbb{Z}_p[x]` is greater than or equal to the degree
    in `\mathbb{Z}[x]`.

    Parameters
    ==========

    f : PolyElement
        univariate integer polynomial
    g : PolyElement
        univariate integer polynomial

    é   r   )r   r   Úgcdr   r   r   r(   r   )r   r   Úgammar"   r    r!   ÚhpÚdeghps           r   Ú_degree_bound_univariater/   :   sŸ   € ð& ŒFŒM×Ò˜aœd A¤DÑ)Ô)€EØ	€Aå�!‰Œ€AØ
�!‰)�qŠ.ˆ.Ý�a‰LŒLˆð �!‰)�qŠ.ˆ.ð 
�Š˜Ñ	Ô	€BØ	
�Š˜Ñ	Ô	€BÝ	��R˜Ñ	Ô	€BØ�IŠI‰KŒK€EØ€Lr   c           	      óT  — |                       ¦   «         }| j        j        d         }| j        j        }t	          |dz   ¦  «        D ]N}t          ||g|                      ||z  ¦  «        |                     ||z  ¦  «        gd¬¦  «        d         ||f<   ŒO|                     ¦   «          |S )a�  
    Construct a polynomial `h_{pq}` in `\mathbb{Z}_{p q}[x]` such that

    .. math ::

        h_{pq} = h_p \; \mathrm{mod} \, p

        h_{pq} = h_q \; \mathrm{mod} \, q

    for relatively prime integers `p` and `q` and polynomials
    `h_p` and `h_q` in `\mathbb{Z}_p[x]` and `\mathbb{Z}_q[x]`
    respectively.

    The coefficients of the polynomial `h_{pq}` are computed with the
    Chinese Remainder Theorem. The symmetric representation in
    `\mathbb{Z}_p[x]`, `\mathbb{Z}_q[x]` and `\mathbb{Z}_{p q}[x]` is used.
    It is assumed that `h_p` and `h_q` have the same degree.

    Parameters
    ==========

    hp : PolyElement
        univariate integer polynomial with coefficients in `\mathbb{Z}_p`
    hq : PolyElement
        univariate integer polynomial with coefficients in `\mathbb{Z}_q`
    p : Integer
        modulus of `h_p`, relatively prime to `q`
    q : Integer
        modulus of `h_q`, relatively prime to `p`

    Examples
    ========

    >>> from sympy.polys.modulargcd import _chinese_remainder_reconstruction_univariate
    >>> from sympy.polys import ring, ZZ

    >>> R, x = ring("x", ZZ)
    >>> p = 3
    >>> q = 5

    >>> hp = -x**3 - 1
    >>> hq = 2*x**3 - 2*x**2 + x

    >>> hpq = _chinese_remainder_reconstruction_univariate(hp, hq, p, q)
    >>> hpq
    2*x**3 + 3*x**2 + 6*x + 5

    >>> hpq.trunc_ground(p) == hp
    True
    >>> hpq.trunc_ground(q) == hq
    True

    r   r*   T©Ú	symmetric)r   r   Úgensr   Úranger   ÚcoeffÚ
strip_zero)r-   Úhqr"   ÚqÚnÚxÚhpqÚis           r   Ú,_chinese_remainder_reconstruction_univariater=   [   sŸ   € ðl 	�	Š	‰Œ€AØ
ŒŒ�QŒ€AØ
Œ'Œ,€Cå�1�Q‘3‰ZŒZð Uð UˆÝ˜˜A˜ §¢¨!¨Q©$¡¤°·²¸!¸Q¹$±´Ð @ÈDÐQÑQÔQÐRSÔTˆˆQˆD‰	ˆ	à‡N‚NÑÔÐØ€Jr   c                 ó6  — | j         |j         k    r| j         j        j        sJ ‚t          | |¦  «        }|�|S | j         }|                      ¦   «         \  }} |                     ¦   «         \  }}|j                             ||¦  «        }t          | |¦  «        }|dk    r: ||¦  «        |                      ||z  ¦  «        |                     ||z  ¦  «        fS |j                             | j        |j        ¦  «        }d}	d}
	 t          |
¦  «        }
||
z  dk    rt          |
¦  «        }
||
z  dk    °|  
                    |
¦  «        }| 
                    |
¦  «        }t          |||
¦  «        }|                     ¦   «         }||k    rŒ‡||k     rd}	|}Œ’|                     |¦  «         
                    |
¦  «        }|	dk    r|
}	|}ŒÅt          |||
|	¦  «        }|	|
z  }	||k    s|}Œå|                     |                     ¦   «         ¦  «        }|                      |¦  «        \  }}|                     |¦  «        \  }}|sZ|sX|j        dk     r| }|                     |¦  «        }|                     ||z  ¦  «        }|                     ||z  ¦  «        }|||fS �Œ™)a’  
    Computes the GCD of two polynomials in `\mathbb{Z}[x]` using a modular
    algorithm.

    The algorithm computes the GCD of two univariate integer polynomials
    `f` and `g` by computing the GCD in `\mathbb{Z}_p[x]` for suitable
    primes `p` and then reconstructing the coefficients with the Chinese
    Remainder Theorem. Trial division is only made for candidates which
    are very likely the desired GCD.

    Parameters
    ==========

    f : PolyElement
        univariate integer polynomial
    g : PolyElement
        univariate integer polynomial

    Returns
    =======

    h : PolyElement
        GCD of the polynomials `f` and `g`
    cff : PolyElement
        cofactor of `f`, i.e. `\frac{f}{h}`
    cfg : PolyElement
        cofactor of `g`, i.e. `\frac{g}{h}`

    Examples
    ========

    >>> from sympy.polys.modulargcd import modgcd_univariate
    >>> from sympy.polys import ring, ZZ

    >>> R, x = ring("x", ZZ)

    >>> f = x**5 - 1
    >>> g = x - 1

    >>> h, cff, cfg = modgcd_univariate(f, g)
    >>> h, cff, cfg
    (x - 1, x**4 + x**3 + x**2 + x + 1, 1)

    >>> cff * h == f
    True
    >>> cfg * h == g
    True

    >>> f = 6*x**2 - 6
    >>> g = 2*x**2 + 4*x + 2

    >>> h, cff, cfg = modgcd_univariate(f, g)
    >>> h, cff, cfg
    (2*x + 2, 3*x - 3, x + 1)

    >>> cff * h == f
    True
    >>> cfg * h == g
    True

    References
    ==========

    1. [Monagan00]_

    Nr   r*   )r   r   Úis_ZZr   Ú	primitiver+   r/   r   r   r   r   r(   r   r=   Ú
quo_groundÚcontentÚdiv)r   r   Úresultr   ÚcfÚcgÚchÚboundr,   Úmr"   r    r!   r-   r.   ÚhlastmÚhmÚhÚfquoÚfremÚgquoÚgremÚcffÚcfgs                           r   Úmodgcd_univariaterS   œ   s˜  € ðF Œ6�Q”VÒÐ ¤¤Ô 3ÐÐÐ3å˜!˜QÑÔ€FØÐØˆàŒ6€Dà�KŠK‰MŒM�E€BˆØ�KŠK‰MŒM�E€BˆØ	Œ�Š˜˜RÑ	 Ô	 €Bå$ Q¨Ñ*Ô*€EØ�‚z€zØˆt�B‰xŒx˜Ÿš b¨B¡hÑ/Ô/°·²¸bÀB¹hÑ1GÔ1GÐGÐGàŒK�OŠO˜AœD !¤$Ñ'Ô'€EØ	€AØ	€Að'Ý�a‰LŒLˆØ�a‰i˜1ŠnˆnÝ˜!‘”ˆAð �a‰i˜1Šnˆnð �^Š^˜AÑÔˆØ�^Š^˜AÑÔˆÝ�R˜˜QÑÔˆØ—	’	‘”ˆà�5Š=ˆ=ØØ�UŠ]ˆ]ØˆAØˆEØà�]Š]˜5Ñ!Ô!×.Ò.¨qÑ1Ô1ˆØ�Š6ˆ6ØˆAØˆFØå9¸"¸fÀaÈÑKÔKˆØ	ˆQ‰ˆà�VŠ|ˆ|ØˆFØà�MŠM˜"Ÿ*š*™,œ,Ñ'Ô'ˆØ—U’U˜1‘X”X‰
ˆˆdØ—U’U˜1‘X”X‰
ˆˆdØð 	˜Dð 	ØŒt�aŠxˆxØ�S�Ø—’˜RÑ Ô ˆAØ—/’/ "¨¡(Ñ+Ô+ˆCØ—/’/ "¨¡(Ñ+Ô+ˆCØ�c˜3�;ÐñO'r   c           	      óB  — | j         }|j        }|j        }i }|                      ¦   «         D ]7\  }}|dd…         |vri ||dd…         <   |||dd…                  |d         <   Œ8g }t	          |                     ¦   «         ¦  «        D ]#}t          |t          |||¦  «        ||¦  «        }Œ$|                     |j	        |dz
           ¬¦  «        }	|	 
                    |¦  «                             |¦  «        }
|
|                      |
                     |¦  «        ¦  «        fS )a€  
    Compute the content and the primitive part of a polynomial in
    `\mathbb{Z}_p[x_0, \ldots, x_{k-2}, y] \cong \mathbb{Z}_p[y][x_0, \ldots, x_{k-2}]`.

    Parameters
    ==========

    f : PolyElement
        integer polynomial in `\mathbb{Z}_p[x0, \ldots, x{k-2}, y]`
    p : Integer
        modulus of `f`

    Returns
    =======

    contf : PolyElement
        integer polynomial in `\mathbb{Z}_p[y]`, content of `f`
    ppf : PolyElement
        primitive part of `f`, i.e. `\frac{f}{contf}`

    Examples
    ========

    >>> from sympy.polys.modulargcd import _primitive
    >>> from sympy.polys import ring, ZZ

    >>> R, x, y = ring("x, y", ZZ)
    >>> p = 3

    >>> f = x**2*y**2 + x**2*y - y**2 - y
    >>> _primitive(f, p)
    (y**2 + y, x**2 - 1)

    >>> R, x, y, z = ring("x, y, z", ZZ)

    >>> f = x*y*z - y**2*z**2
    >>> _primitive(f, p)
    (z, x*y - y**2*z)

    Néÿÿÿÿr*   ©Úsymbols)r   r   ÚngensÚ	itertermsÚiterÚvaluesr   r	   ÚclonerW   Ú
from_denser   ÚquoÚset_ring)r   r"   r   r#   ÚkÚcoeffsÚmonomr5   ÚcontÚyringÚcontfs              r   Ú
_primitiverf     s&  € ðR Œ6€DØ
Œ+€CØŒ
€Aà€FØŸš™œð .ð .‰ˆˆuØ��"�Œ:˜VÐ#Ð#Ø!#ˆF�5˜˜"˜”:ÑØ(-ˆˆu�S�b�SŒzÔ˜5 œ9Ñ%Ð%à€DÝ�f—m’m‘o”oÑ&Ô&ð Að AˆÝ�d�L¨°°3Ñ7Ô7¸¸CÑ@Ô@ˆˆà�JŠJ˜tœ|¨A¨a©CÔ0ˆJÑ1Ô1€EØ×Ò˜TÑ"Ô"×/Ò/°Ñ2Ô2€Eà�!—%’%˜Ÿš tÑ,Ô,Ñ-Ô-Ð-Ð-r   c                 óŒ   — | j         j        }d|dz
  z  }|                      ¦   «         D ]}|dd…         |k    r
|dd…         }Œ|S )aÆ  
    Compute the degree of a multivariate polynomial
    `f \in K[x_0, \ldots, x_{k-2}, y] \cong K[y][x_0, \ldots, x_{k-2}]`.

    Parameters
    ==========

    f : PolyElement
        polynomial in `K[x_0, \ldots, x_{k-2}, y]`

    Returns
    =======

    degf : Integer tuple
        degree of `f` in `x_0, \ldots, x_{k-2}`

    Examples
    ========

    >>> from sympy.polys.modulargcd import _deg
    >>> from sympy.polys import ring, ZZ

    >>> R, x, y = ring("x, y", ZZ)

    >>> f = x**2*y**2 + x**2*y - 1
    >>> _deg(f)
    (2,)

    >>> R, x, y, z = ring("x, y, z", ZZ)

    >>> f = x**2*y**2 + x**2*y - 1
    >>> _deg(f)
    (2, 2)

    >>> f = x*y*z - y**2*z**2
    >>> _deg(f)
    (1, 1)

    )r   r*   NrU   )r   rX   Ú
itermonoms)r   r`   Údegfrb   s       r   Ú_degrj   Z  sX   € ðP 	
ŒŒ€AØ�1�Q‘3‰<€DØ—’‘”ð ð ˆØ��"�Œ:˜ÒÐØ˜˜"˜”:ˆDøØ€Kr   c                 ó"  — | j         }|j        }|                     |j        |dz
           ¬¦  «        }|j        d         }t          | ¦  «        }|j        }|                      ¦   «         D ]$\  }}|dd…         |k    r||||d         z  z  z  }Œ%|S )aÏ  
    Compute the leading coefficient of a multivariate polynomial
    `f \in K[x_0, \ldots, x_{k-2}, y] \cong K[y][x_0, \ldots, x_{k-2}]`.

    Parameters
    ==========

    f : PolyElement
        polynomial in `K[x_0, \ldots, x_{k-2}, y]`

    Returns
    =======

    lcf : PolyElement
        polynomial in `K[y]`, leading coefficient of `f`

    Examples
    ========

    >>> from sympy.polys.modulargcd import _LC
    >>> from sympy.polys import ring, ZZ

    >>> R, x, y = ring("x, y", ZZ)

    >>> f = x**2*y**2 + x**2*y - 1
    >>> _LC(f)
    y**2 + y

    >>> R, x, y, z = ring("x, y, z", ZZ)

    >>> f = x**2*y**2 + x**2*y - 1
    >>> _LC(f)
    1

    >>> f = x*y*z - y**2*z**2
    >>> _LC(f)
    z

    r*   rV   r   NrU   )r   rX   r\   rW   r3   rj   r   rY   )	r   r   r`   rd   Úyri   Úlcfrb   r5   s	            r   Ú_LCrn   Š  s™   € ðP Œ6€DØŒ
€AØ�JŠJ˜tœ|¨A¨a©CÔ0ˆJÑ1Ô1€EØŒ
�1Œ€AÝ�‰7Œ7€Dà
Œ*€CØŸš™œð &ð &‰ˆˆuØ��"�Œ:˜ÒÐØ�5˜˜E "œI™Ñ%Ñ%ˆCøØ€Jr   c                 ó¤   — | j         }|j        }|                      ¦   «         D ],\  }}||         f|d|…         z   ||dz   d…         z   }|||<   Œ-|S )zS
    Make the variable `x_i` the leading one in a multivariate polynomial `f`.
    Nr*   )r   r   rY   )r   r<   r   Úfswaprb   r5   Ú	monomswaps          r   Ú_swaprr   ¿  sh   € ð Œ6€DØŒI€EØŸš™œð !ð !‰ˆˆuØ˜1”X�K %¨¨¨¤)Ñ+¨e°A°a±C°D°D¬kÑ9ˆ	Ø ˆˆiÑÐØ€Lr   c                 óF  — | j         }|j                             | j        |j        ¦  «        }|j                             t	          | d¦  «        j        t	          |d¦  «        j        ¦  «        }||z  }d}t          |¦  «        }||z  dk    rt          |¦  «        }||z  dk    °|                      |¦  «        }|                     |¦  «        }t          ||¦  «        \  }	}t          ||¦  «        \  }
}t          |	|
|¦  «        }| 	                    ¦   «         }t          t          |¦  «        t          |¦  «        |¦  «        }t          |¦  «        D ]˜}|                     d|¦  «        |z  sŒ|                     d|¦  «                             |¦  «        }|                     d|¦  «                             |¦  «        }t          |||¦  «        }| 	                    ¦   «         }||fc S t          | 	                    ¦   «         | 	                    ¦   «         ¦  «        |fS )a§  
    Compute upper degree bounds for the GCD of two bivariate
    integer polynomials `f` and `g`.

    The GCD is viewed as a polynomial in `\mathbb{Z}[y][x]` and the
    function returns an upper bound for its degree and one for the degree
    of its content. This is done by choosing a suitable prime `p` and
    computing the GCD of the contents of `f \; \mathrm{mod} \, p` and
    `g \; \mathrm{mod} \, p`. The choice of `p` guarantees that the degree
    of the content in `\mathbb{Z}_p[y]` is greater than or equal to the
    degree in `\mathbb{Z}[y]`. To obtain the degree bound in the variable
    `x`, the polynomials are evaluated at `y = a` for a suitable
    `a \in \mathbb{Z}_p` and then their GCD in `\mathbb{Z}_p[x]` is
    computed. If no such `a` exists, i.e. the degree in `\mathbb{Z}_p[x]`
    is always smaller than the one in `\mathbb{Z}[y][x]`, then the bound is
    set to the minimum of the degrees of `f` and `g` in `x`.

    Parameters
    ==========

    f : PolyElement
        bivariate integer polynomial
    g : PolyElement
        bivariate integer polynomial

    Returns
    =======

    xbound : Integer
        upper bound for the degree of the GCD of the polynomials `f` and
        `g` in the variable `x`
    ycontbound : Integer
        upper bound for the degree of the content of the GCD of the
        polynomials `f` and `g` in the variable `y`

    References
    ==========

    1. [Monagan00]_

    r*   r   )r   r   r+   r   rr   r   r   rf   r(   r   rn   r4   ÚevaluateÚmin)r   r   r   Úgamma1Úgamma2Ú	badprimesr"   r    r!   ÚcontfpÚcontgpÚconthpÚ
ycontboundÚdeltaÚaÚfpaÚgpaÚhpaÚxbounds                      r   Ú_degree_bound_bivariaterƒ   Ë  sâ  € ðT Œ6€DàŒ[�_Š_˜QœT 1¤4Ñ(Ô(€FØŒ[�_Š_�U 1 a™[œ[œ^­U°1°a©[¬[¬^Ñ<Ô<€FØ˜‘€IØ	€Aå�!‰Œ€AØ
�a‰-˜1Ò
Ð
Ý�a‰LŒLˆð �a‰-˜1Ò
Ð
ð 
�Š˜Ñ	Ô	€BØ	
�Š˜Ñ	Ô	€BÝ˜B Ñ"Ô"�J€FˆBÝ˜B Ñ"Ô"�J€FˆBÝ�V˜V QÑ'Ô'€FØ—’‘”€Jõ •C˜‘G”G�S ™WœW aÑ(Ô(€Eå�1‰XŒXð "ð "ˆØ�~Š~˜a Ñ#Ô# aÑ'ð 	ØØ�kŠk˜!˜QÑÔ×,Ò,¨QÑ/Ô/ˆØ�kŠk˜!˜QÑÔ×,Ò,¨QÑ/Ô/ˆÝ�c˜3 Ñ"Ô"ˆØ—’‘”ˆØ�zÐ!Ð!Ð!Ð!åˆr�yŠy‰{Œ{˜BŸIšI™KœKÑ(Ô(¨*Ð4Ð4r   c                 óT  ‡— t          |                      ¦   «         ¦  «        }t          |                     ¦   «         ¦  «        }|                     |¦  «        }|                     |¦  «         |                     |¦  «         | j        j        Š‰j        }| j        j        }t          | j        j        t          ¦  «        rt          }	nˆfd„}	|D ]}
 |	| |
         ||
         ||¦  «        ||
<   Œ |D ]}
 |	| |
         |||¦  «        ||
<   Œ|D ]}
 |	|||
         ||¦  «        ||
<   Œ|S )a:  
    Construct a polynomial `h_{pq}` in
    `\mathbb{Z}_{p q}[x_0, \ldots, x_{k-1}]` such that

    .. math ::

        h_{pq} = h_p \; \mathrm{mod} \, p

        h_{pq} = h_q \; \mathrm{mod} \, q

    for relatively prime integers `p` and `q` and polynomials
    `h_p` and `h_q` in `\mathbb{Z}_p[x_0, \ldots, x_{k-1}]` and
    `\mathbb{Z}_q[x_0, \ldots, x_{k-1}]` respectively.

    The coefficients of the polynomial `h_{pq}` are computed with the
    Chinese Remainder Theorem. The symmetric representation in
    `\mathbb{Z}_p[x_0, \ldots, x_{k-1}]`,
    `\mathbb{Z}_q[x_0, \ldots, x_{k-1}]` and
    `\mathbb{Z}_{p q}[x_0, \ldots, x_{k-1}]` is used.

    Parameters
    ==========

    hp : PolyElement
        multivariate integer polynomial with coefficients in `\mathbb{Z}_p`
    hq : PolyElement
        multivariate integer polynomial with coefficients in `\mathbb{Z}_q`
    p : Integer
        modulus of `h_p`, relatively prime to `q`
    q : Integer
        modulus of `h_q`, relatively prime to `p`

    Examples
    ========

    >>> from sympy.polys.modulargcd import _chinese_remainder_reconstruction_multivariate
    >>> from sympy.polys import ring, ZZ

    >>> R, x, y = ring("x, y", ZZ)
    >>> p = 3
    >>> q = 5

    >>> hp = x**3*y - x**2 - 1
    >>> hq = -x**3*y - 2*x*y**2 + 2

    >>> hpq = _chinese_remainder_reconstruction_multivariate(hp, hq, p, q)
    >>> hpq
    4*x**3*y + 5*x**2 + 3*x*y**2 + 2

    >>> hpq.trunc_ground(p) == hp
    True
    >>> hpq.trunc_ground(q) == hq
    True

    >>> R, x, y, z = ring("x, y, z", ZZ)
    >>> p = 6
    >>> q = 5

    >>> hp = 3*x**4 - y**3*z + z
    >>> hq = -2*x**4 + z

    >>> hpq = _chinese_remainder_reconstruction_multivariate(hp, hq, p, q)
    >>> hpq
    3*x**4 + 5*y**3*z + z

    >>> hpq.trunc_ground(p) == hp
    True
    >>> hpq.trunc_ground(q) == hq
    True

    c                 óN   •—  ‰t          ||g| |gd¬¦  «        d         ¦  «        S )NTr1   r   r   )ÚcpÚcqr"   r8   r   s       €r   Úcrt_z<_chinese_remainder_reconstruction_multivariate.<locals>.crt_l  s/   ø€ Ø�6�#˜q !˜f r¨2 h¸$Ð?Ñ?Ô?ÀÔBÑCÔCÐCr   )
ÚsetÚmonomsÚintersectionÚdifference_updater   r   r   Ú
isinstancer   Ú._chinese_remainder_reconstruction_multivariate)r-   r7   r"   r8   ÚhpmonomsÚhqmonomsrŠ   r   r;   rˆ   rb   r   s              @r   rŽ   rŽ     sU  ø€ õP �2—9’9‘;”;ÑÔ€HÝ�2—9’9‘;”;ÑÔ€HØ×"Ò" 8Ñ,Ô,€FØ×Ò˜vÑ&Ô&Ð&Ø×Ò˜vÑ&Ô&Ð&àŒWŒ^€FØŒ;€Dà
Œ'Œ,€Cå�"”'”.¥.Ñ1Ô1ð DÝ=ˆˆð	Dð 	Dð 	Dð 	Dð 	Dð ð 6ð 6ˆØ�T˜"˜Uœ) R¨¤Y°°1Ñ5Ô5ˆˆE‰
ˆ
Øð 1ð 1ˆØ�T˜"˜Uœ) T¨1¨aÑ0Ô0ˆˆE‰
ˆ
Øð 1ð 1ˆØ�T˜$  5¤	¨1¨aÑ0Ô0ˆˆE‰
ˆ
à€Jr   Fc                 ó°  — |j         }|r|j        j        }|j        j        |         }n|j        }|j        |         }t          | |¦  «        D ]u\  }	}
|j        }|j        }| D ]}||	k    rŒ	|||z
  z  }||	|z
  z  }Œ|                     ||¦  «        }|                     |¦  «        }||
                     |¦  «        |z  z  }Œv|                     |¦  «        S )a  
    Reconstruct a polynomial `h_p` in `\mathbb{Z}_p[x_0, \ldots, x_{k-1}]`
    from a list of evaluation points in `\mathbb{Z}_p` and a list of
    polynomials in
    `\mathbb{Z}_p[x_0, \ldots, x_{i-1}, x_{i+1}, \ldots, x_{k-1}]`, which
    are the images of `h_p` evaluated in the variable `x_i`.

    It is also possible to reconstruct a parameter of the ground domain,
    i.e. if `h_p` is a polynomial over `\mathbb{Z}_p[x_0, \ldots, x_{k-1}]`.
    In this case, one has to set ``ground=True``.

    Parameters
    ==========

    evalpoints : list of Integer objects
        list of evaluation points in `\mathbb{Z}_p`
    hpeval : list of PolyElement objects
        list of polynomials in (resp. over)
        `\mathbb{Z}_p[x_0, \ldots, x_{i-1}, x_{i+1}, \ldots, x_{k-1}]`,
        images of `h_p` evaluated in the variable `x_i`
    ring : PolyRing
        `h_p` will be an element of this ring
    i : Integer
        index of the variable which has to be reconstructed
    p : Integer
        prime number, modulus of `h_p`
    ground : Boolean
        indicates whether `x_i` is in the ground domain, default is
        ``False``

    Returns
    =======

    hp : PolyElement
        interpolated polynomial in (resp. over)
        `\mathbb{Z}_p[x_0, \ldots, x_{k-1}]`

    )	r   r   r3   Úzipr   r   r   r_   r   )Ú
evalpointsÚhpevalr   r<   r"   Úgroundr-   r   rl   r~   r�   ÚnumerÚdenomÚbr5   s                  r   Ú_interpolate_multivariater™   y  sø   € ðN 
Œ€Bàð Ø”Ô#ˆØŒKÔ˜QÔˆˆà”ˆØŒI�aŒLˆå�j &Ñ)Ô)ð )ð )‰ˆˆ3Ø”ˆØ”
ˆØð 	ð 	ˆAØ�AŠvˆvØà�Q˜‘U‰NˆEØ�Q˜‘U‰NˆEˆEà—’˜e QÑ'Ô'ˆØ× Ò  Ñ'Ô'ˆØ
ˆc�lŠl˜4Ñ Ô  5Ñ(Ñ(ˆˆà�?Š?˜1ÑÔÐr   c                 óŽ  — | j         |j         k    r| j         j        j        sJ ‚t          | |¦  «        }|�|S | j         }|                      ¦   «         \  }} |                     ¦   «         \  }}|j                             ||¦  «        }t          | |¦  «        \  }}||cxk    rdk    r=n n: ||¦  «        |                      ||z  ¦  «        |                     ||z  ¦  «        fS t          | d¦  «        }	t          |d¦  «        }
|	 	                    ¦   «         }|
 	                    ¦   «         }t          |	|
¦  «        \  }}||cxk    rdk    r=n n: ||¦  «        |                      ||z  ¦  «        |                     ||z  ¦  «        fS |j                             | j
        |j
        ¦  «        }|j                             |	j
        |
j
        ¦  «        }||z  }d}d}	 t          |¦  «        }||z  dk    rt          |¦  «        }||z  dk    °|                      |¦  «        }|                     |¦  «        }t          ||¦  «        \  }}t          ||¦  «        \  }}t          |||¦  «        }| 	                    ¦   «         }||k    rŒ­||k     rd}|}Œ¸t          t          |¦  «        t          |¦  «        |¦  «        }| 	                    ¦   «         }| 	                    ¦   «         }| 	                    ¦   «         }t!          ||z
  ||z
  ||z
  |z   ¦  «        dz   }||k     r�ŒGd}g } g }!d}"t#          |¦  «        D �]
}#|                     d|#¦  «        }$|$|z  sŒ|                     d|#¦  «                             |¦  «        }%|                     d|#¦  «                             |¦  «        }&t          |%|&|¦  «        }'|' 	                    ¦   «         }(|(|k    rŒ�|(|k     rd}|(}d}" na|'                     |$¦  «                             |¦  «        }'|                      |#¦  «         |!                     |'¦  «         |dz  }||k    r n�Œ|"r�Œn||k     r�Œvt)          | |!|d|¦  «        })t          |)|¦  «        d         })|)|                     |¦  «        z  })|) 	                    d¦  «        }*|*|k    r�ŒÔ|*|k     rd}|*}�Œà|)                     |¦  «                             |¦  «        })|dk    r|}|)}+�Œt-          |)|+||¦  «        },||z  }|,|+k    s|,}+�Œ5|,                     |,                     ¦   «         ¦  «        }-|                      |-¦  «        \  }.}/|                     |-¦  «        \  }0}1|/sZ|1sX|-j
        dk     r| }|-                     |¦  «        }-|.                     ||z  ¦  «        }2|0                     ||z  ¦  «        }3|-|2|3fS �Œé)a!  
    Computes the GCD of two polynomials in `\mathbb{Z}[x, y]` using a
    modular algorithm.

    The algorithm computes the GCD of two bivariate integer polynomials
    `f` and `g` by calculating the GCD in `\mathbb{Z}_p[x, y]` for
    suitable primes `p` and then reconstructing the coefficients with the
    Chinese Remainder Theorem. To compute the bivariate GCD over
    `\mathbb{Z}_p`, the polynomials `f \; \mathrm{mod} \, p` and
    `g \; \mathrm{mod} \, p` are evaluated at `y = a` for certain
    `a \in \mathbb{Z}_p` and then their univariate GCD in `\mathbb{Z}_p[x]`
    is computed. Interpolating those yields the bivariate GCD in
    `\mathbb{Z}_p[x, y]`. To verify the result in `\mathbb{Z}[x, y]`, trial
    division is done, but only for candidates which are very likely the
    desired GCD.

    Parameters
    ==========

    f : PolyElement
        bivariate integer polynomial
    g : PolyElement
        bivariate integer polynomial

    Returns
    =======

    h : PolyElement
        GCD of the polynomials `f` and `g`
    cff : PolyElement
        cofactor of `f`, i.e. `\frac{f}{h}`
    cfg : PolyElement
        cofactor of `g`, i.e. `\frac{g}{h}`

    Examples
    ========

    >>> from sympy.polys.modulargcd import modgcd_bivariate
    >>> from sympy.polys import ring, ZZ

    >>> R, x, y = ring("x, y", ZZ)

    >>> f = x**2 - y**2
    >>> g = x**2 + 2*x*y + y**2

    >>> h, cff, cfg = modgcd_bivariate(f, g)
    >>> h, cff, cfg
    (x + y, x - y, x + y)

    >>> cff * h == f
    True
    >>> cfg * h == g
    True

    >>> f = x**2*y - x**2 - 4*y + 4
    >>> g = x + 2

    >>> h, cff, cfg = modgcd_bivariate(f, g)
    >>> h, cff, cfg
    (x + 2, x*y - x - 2*y + 2, 1)

    >>> cff * h == f
    True
    >>> cfg * h == g
    True

    References
    ==========

    1. [Monagan00]_

    Nr   r*   TF)r   r   r?   r   r@   r+   rƒ   r   rr   r   r   r   r   rf   r(   rn   ru   r4   rt   Úappendr™   r_   rŽ   rA   rB   rC   )4r   r   rD   r   rE   rF   rG   r‚   r|   rp   ÚgswapÚdegyfÚdegygÚyboundÚ
xcontboundrv   rw   rx   rI   r"   r    r!   ry   rz   r{   Ú	degconthpr}   Ú	degcontfpÚ	degcontgpÚdegdeltaÚNr9   r“   r”   Úunluckyr~   Údeltaar   r€   r�   Údeghpar-   ÚdegyhprJ   rK   rL   rM   rN   rO   rP   rQ   rR   s4                                                       r   Úmodgcd_bivariaterª   º  sí  € ðR Œ6�Q”VÒÐ ¤¤Ô 3ÐÐÐ3å˜!˜QÑÔ€FØÐØˆàŒ6€Dà�KŠK‰MŒM�E€BˆØ�KŠK‰MŒM�E€BˆØ	Œ�Š˜˜RÑ	 Ô	 €Bå0°°AÑ6Ô6Ñ€FˆJØ�Ð Ð Ò Ð ˜qÒ Ð Ð Ð Ð Øˆt�B‰xŒx˜Ÿš b¨B¡hÑ/Ô/°·²¸bÀB¹hÑ1GÔ1GÐGÐGå�!�Q‰KŒK€EÝ�!�Q‰KŒK€EØ�LŠL‰NŒN€EØ�LŠL‰NŒN€Eå0°¸Ñ>Ô>Ñ€FˆJØ�Ð Ð Ò Ð ˜qÒ Ð Ð Ð Ð Øˆt�B‰xŒx˜Ÿš b¨B¡hÑ/Ô/°·²¸bÀB¹hÑ1GÔ1GÐGÐGð Œ[�_Š_˜QœT 1¤4Ñ(Ô(€FØŒ[�_Š_˜UœX u¤xÑ0Ô0€FØ˜‘€IØ	€AØ	€AðgÝ�a‰LŒLˆØ˜!‰m˜qÒ Ð Ý˜!‘”ˆAð ˜!‰m˜qÒ Ð ð �^Š^˜AÑÔˆØ�^Š^˜AÑÔˆÝ  AÑ&Ô&‰
ˆ�Ý  AÑ&Ô&‰
ˆ�Ý˜ ¨Ñ+Ô+ˆØ—M’M‘O”Oˆ	à�zÒ!Ð!ØØ˜Ò#Ð#ØˆAØ"ˆJØõ �˜B™œ¥ R¡¤¨!Ñ,Ô,ˆà—M’M‘O”Oˆ	Ø—M’M‘O”Oˆ	Ø—<’<‘>”>ˆå�˜	Ñ! 5¨9Ñ#4Ø�ZÑ (Ñ*ñ,ô ,Ø./ñ0ˆð ˆqŠ5ˆ5ÙàˆØˆ
ØˆØˆå�q‘”ð 	ñ 	ˆAØ—^’^ A qÑ)Ô)ˆFØ˜A‘:ð Øà—+’+˜a Ñ#Ô#×0Ò0°Ñ3Ô3ˆCØ—+’+˜a Ñ#Ô#×0Ò0°Ñ3Ô3ˆCÝ˜#˜s AÑ&Ô&ˆCØ—Z’Z‘\”\ˆFà˜ŠˆØØ˜&’�Ø�Ø�Ø�Ø�à—.’. Ñ(Ô(×5Ò5°aÑ8Ô8ˆCØ×Ò˜aÑ Ô Ð Ø�MŠM˜#ÑÔÐØ�‰FˆAà�AŠvˆvØ�ñ ð ð 	ÙØˆqŠ5ˆ5Ùå& z°6¸4ÀÀAÑFÔFˆå˜˜AÑÔ˜qÔ!ˆØ�&—/’/ $Ñ'Ô'Ñ'ˆØ—’˜1‘”ˆà�FŠ?ˆ?ÙØ�FŠ?ˆ?ØˆAØˆFÙà�]Š]˜6Ñ"Ô"×/Ò/°Ñ2Ô2ˆØ�Š6ˆ6ØˆAØˆFÙå;¸BÀÈÈ1ÑMÔMˆØ	ˆQ‰ˆà�VŠ|ˆ|ØˆFÙà�MŠM˜"Ÿ*š*™,œ,Ñ'Ô'ˆØ—U’U˜1‘X”X‰
ˆˆdØ—U’U˜1‘X”X‰
ˆˆdØð 	˜Dð 	ØŒt�aŠxˆxØ�S�Ø—’˜RÑ Ô ˆAØ—/’/ "¨¡(Ñ+Ô+ˆCØ—/’/ "¨¡(Ñ+Ô+ˆCØ�c˜3�;ÐñOgr   c                 ó�  — | j         }|j        }|dk    r`t          | ||¦  «                             |¦  «        }|                     ¦   «         }||d         k    rdS ||d         k     r||d<   t
          ‚|S |                      |dz
  ¦  «        }	|                     |dz
  ¦  «        }
t          | |¦  «        \  }} t          ||¦  «        \  }}t          |||¦  «        }|                     ¦   «         }|                     ¦   «         }|                     ¦   «         }|||dz
           k    rdS |||dz
           k     r|||dz
  <   t
          ‚t          | ¦  «        }t          |¦  «        }t          |||¦  «        }|}t          |dz
  ¦  «        D ]L}|t          t          t          | |¦  «        ¦  «        t          t          ||¦  «        ¦  «        |¦  «        z  }ŒM|                     ¦   «         }t          |	|z
  |
|z
  ||dz
           ||dz
           z
  |z   ¦  «        dz   }||k     rdS d}d}g }g }t          t          |¦  «        ¦  «        }|�rút          j        |d¦  «        d         }|                     |¦  «         |                     d|¦  «        |z  sŒM|                     d|¦  «        |z  }|                      |dz
  |¦  «                             |¦  «        }|                     |dz
  |¦  «                             |¦  «        } t!          || |||¦  «        }!|!€|dz  }||k    rdS Œá|!j        r*|                     |¦  «                             |¦  «        }|S |!                     |¦  «                             |¦  «        }!|                     |¦  «         |                     |!¦  «         |dz  }||k    r‹t+          ||||dz
  |¦  «        }t          ||¦  «        d         |                     |¦  «        z  }|                     |dz
  ¦  «        }"|"||dz
           k    rdS |"||dz
           k     r|"||dz
  <   t
          ‚|S |�°údS )a±  
    Compute the GCD of two polynomials in
    `\mathbb{Z}_p[x_0, \ldots, x_{k-1}]`.

    The algorithm reduces the problem step by step by evaluating the
    polynomials `f` and `g` at `x_{k-1} = a` for suitable
    `a \in \mathbb{Z}_p` and then calls itself recursively to compute the GCD
    in `\mathbb{Z}_p[x_0, \ldots, x_{k-2}]`. If these recursive calls are
    successful for enough evaluation points, the GCD in `k` variables is
    interpolated, otherwise the algorithm returns ``None``. Every time a GCD
    or a content is computed, their degrees are compared with the bounds. If
    a degree greater then the bound is encountered, then the current call
    returns ``None`` and a new evaluation point has to be chosen. If at some
    point the degree is smaller, the correspondent bound is updated and the
    algorithm fails.

    Parameters
    ==========

    f : PolyElement
        multivariate integer polynomial with coefficients in `\mathbb{Z}_p`
    g : PolyElement
        multivariate integer polynomial with coefficients in `\mathbb{Z}_p`
    p : Integer
        prime number, modulus of `f` and `g`
    degbound : list of Integer objects
        ``degbound[i]`` is an upper bound for the degree of the GCD of `f`
        and `g` in the variable `x_i`
    contbound : list of Integer objects
        ``contbound[i]`` is an upper bound for the degree of the content of
        the GCD in `\mathbb{Z}_p[x_i][x_0, \ldots, x_{i-1}]`,
        ``contbound[0]`` is not used can therefore be chosen
        arbitrarily.

    Returns
    =======

    h : PolyElement
        GCD of the polynomials `f` and `g` or ``None``

    References
    ==========

    1. [Monagan00]_
    2. [Brown71]_

    r*   r   N)r   rX   r(   r   r   r   rf   rn   r4   rr   ru   ÚlistÚrandomÚsampleÚremovert   Ú_modgcd_multivariate_pÚ	is_groundr_   r   r›   r™   )#r   r   r"   ÚdegboundÚ	contboundr   r`   rL   Údeghr�   rž   re   ÚcontgÚconthÚdegcontfÚdegcontgÚdegconthrm   Úlcgr}   Úevaltestr<   r¤   r¥   r9   Údr“   ÚhevalÚpointsr~   r§   ÚfaÚgaÚhaÚdegyhs#                                      r   r°   r°   Ž  sX  € ð` Œ6€DØŒ
€AàˆA‚v€vÝ�A�q˜!ÑÔ×)Ò)¨!Ñ,Ô,ˆØ�xŠx‰zŒzˆà�(˜1”+ÒÐØ�4Ø�(˜1”+ÒÐØˆH�Q‰KÝ"Ð"àˆà�HŠH�Q�q‘S‰MŒM€EØ�HŠH�Q�q‘S‰MŒM€Eå˜!˜QÑÔ�H€Eˆ1Ý˜!˜QÑÔ�H€Eˆ1å�E˜5 !Ñ$Ô$€Eà�|Š|‰~Œ~€HØ�|Š|‰~Œ~€HØ�|Š|‰~Œ~€Hà�)˜A˜a™C”.Ò Ð ØˆtØ�)˜A˜a™C”.Ò Ð Ø!ˆ	�!�A‘#‰ÝÐå
ˆa‰&Œ&€CÝ
ˆa‰&Œ&€Cå�C˜˜aÑ Ô €Eà€Hå�1�Q‘3‰ZŒZð Cð CˆØ•G�C¥ a¨¡¤Ñ,Ô,­cµ%¸¸1±+´+Ñ.>Ô.>ÀÑBÔBÑBˆˆà�|Š|‰~Œ~€HåˆE�HÑ˜e hÑ.Ø�Q�q‘SŒM˜I a¨¡cœNÑ*¨XÑ5ñ	7ô 	7Ø9:ñ	;€Að 	ˆ1‚u€uØˆtà	€AØ	€AØ€JØ€EÝ•%˜‘(”(‰^Œ^€Fà
ñ +ÝŒM˜& !Ñ$Ô$ QÔ'ˆØ�Š�aÑÔÐà× Ò   AÑ&Ô&¨Ñ*ð 	Øà—’  1Ñ%Ô%¨Ñ)ˆà�ZŠZ˜˜!™˜QÑÔ×,Ò,¨QÑ/Ô/ˆØ�ZŠZ˜˜!™˜QÑÔ×,Ò,¨QÑ/Ô/ˆõ $ B¨¨A¨x¸ÑCÔCˆàˆ:Ø�‰FˆAØ�1ŠuˆuØ�tØàŒ<ð 	Ø—’˜tÑ$Ô$×1Ò1°!Ñ4Ô4ˆAØˆHà�]Š]˜6Ñ"Ô"×/Ò/°Ñ2Ô2ˆà×Ò˜!ÑÔÐØ�Š�RÑÔÐØ	ˆQ‰ˆà�Š6ˆ6Ý)¨*°e¸TÀ1ÀQÁ3ÈÑJÔJˆAå˜1˜aÑ Ô  Ô# e§n¢n°TÑ&:Ô&:Ñ:ˆAØ—H’H˜Q˜q™S‘M”MˆEà�x  !¡”}Ò$Ð$Ø�tØ�x  !¡”}Ò$Ð$Ø %�˜˜1™‘Ý&Ð&àˆHðW ñ +ðZ ˆ4r   c           	      óÎ  — | j         |j         k    r| j         j        j        sJ ‚t          | |¦  «        }|�|S | j         }|j        }|                      ¦   «         \  }} |                     ¦   «         \  }}|j                             ||¦  «        }|j                             | j        |j        ¦  «        }|j        j        }	t          |¦  «        D ]F}
|	|j                             t          | |
¦  «        j        t          ||
¦  «        j        ¦  «        z  }	ŒGd„ t          |                      ¦   «         |                     ¦   «         ¦  «        D ¦   «         }t          |¦  «        }d}d}	 t          |¦  «        }|	|z  dk    rt          |¦  «        }|	|z  dk    °|                      |¦  «        }|                     |¦  «        }	 t!          |||||¦  «        }n# t"          $ r d}Y Œ~w xY w|€Œ…|                     |¦  «                             |¦  «        }|dk    r|}|}Œ¸t'          ||||¦  «        }||z  }||k    s|}ŒØ|                     ¦   «         d         }|                      |¦  «        \  }}|                     |¦  «        \  }}|sZ|sX|j        dk     r| }|                     |¦  «        }|                     ||z  ¦  «        }|                     ||z  ¦  «        }|||fS �Œ)aþ  
    Compute the GCD of two polynomials in `\mathbb{Z}[x_0, \ldots, x_{k-1}]`
    using a modular algorithm.

    The algorithm computes the GCD of two multivariate integer polynomials
    `f` and `g` by calculating the GCD in
    `\mathbb{Z}_p[x_0, \ldots, x_{k-1}]` for suitable primes `p` and then
    reconstructing the coefficients with the Chinese Remainder Theorem. To
    compute the multivariate GCD over `\mathbb{Z}_p` the recursive
    subroutine :func:`_modgcd_multivariate_p` is used. To verify the result in
    `\mathbb{Z}[x_0, \ldots, x_{k-1}]`, trial division is done, but only for
    candidates which are very likely the desired GCD.

    Parameters
    ==========

    f : PolyElement
        multivariate integer polynomial
    g : PolyElement
        multivariate integer polynomial

    Returns
    =======

    h : PolyElement
        GCD of the polynomials `f` and `g`
    cff : PolyElement
        cofactor of `f`, i.e. `\frac{f}{h}`
    cfg : PolyElement
        cofactor of `g`, i.e. `\frac{g}{h}`

    Examples
    ========

    >>> from sympy.polys.modulargcd import modgcd_multivariate
    >>> from sympy.polys import ring, ZZ

    >>> R, x, y = ring("x, y", ZZ)

    >>> f = x**2 - y**2
    >>> g = x**2 + 2*x*y + y**2

    >>> h, cff, cfg = modgcd_multivariate(f, g)
    >>> h, cff, cfg
    (x + y, x - y, x + y)

    >>> cff * h == f
    True
    >>> cfg * h == g
    True

    >>> R, x, y, z = ring("x, y, z", ZZ)

    >>> f = x*z**2 - y*z**2
    >>> g = x**2*z + z

    >>> h, cff, cfg = modgcd_multivariate(f, g)
    >>> h, cff, cfg
    (z, x*z - y*z, x**2 + 1)

    >>> cff * h == f
    True
    >>> cfg * h == g
    True

    References
    ==========

    1. [Monagan00]_
    2. [Brown71]_

    See also
    ========

    _modgcd_multivariate_p

    Nc                 ó4   — g | ]\  }}t          ||¦  «        ‘ŒS © )ru   )Ú.0ÚfdegÚgdegs      r   ú
<listcomp>z'modgcd_multivariate.<locals>.<listcomp>‰  s$   € ÐPÐPÐP¡J D¨$•�D˜$‘”ÐPÐPÐPr   r*   Tr   )r   r   r?   r   rX   r@   r+   r   r   r4   rr   r’   Údegreesr¬   r   r   r°   r   r   rŽ   rC   )r   r   rD   r   r`   rE   rF   rG   r,   rx   r<   r²   r³   rI   r"   r    r!   r-   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   s                              r   Úmodgcd_multivariaterË   '  sä  € ð\ Œ6�Q”VÒÐ ¤¤Ô 3ÐÐÐ3å˜!˜QÑÔ€FØÐØˆàŒ6€DØŒ
€Að �KŠK‰MŒM�E€BˆØ�KŠK‰MŒM�E€BˆØ	Œ�Š˜˜RÑ	 Ô	 €BàŒK�OŠO˜AœD !¤$Ñ'Ô'€Eà””€IÝ�1‰XŒXð Eð EˆØ�T”[—_’_¥U¨1¨a¡[¤[¤^µU¸1¸a±[´[´^ÑDÔDÑDˆ	ˆ	àPÐPµ#°a·i²i±k´kÀ1Ç9Â9Á;Ä;Ñ2OÔ2OÐPÑPÔP€HÝ�X‘”€Ià	€AØ	€Að(Ý�a‰LŒLˆØ˜!‰m˜qÒ Ð Ý˜!‘”ˆAð ˜!‰m˜qÒ Ð ð �^Š^˜AÑÔˆØ�^Š^˜AÑÔˆð	å'¨¨B°°8¸YÑGÔGˆBˆBøÝð 	ð 	ð 	ØˆAØˆHð	øøøð ˆ:Øà�]Š]˜5Ñ!Ô!×.Ò.¨qÑ1Ô1ˆØ�Š6ˆ6ØˆAØˆFØå;¸BÀÈÈ1ÑMÔMˆØ	ˆQ‰ˆà�VŠ|ˆ|ØˆFØà�LŠL‰NŒN˜1ÔˆØ—U’U˜1‘X”X‰
ˆˆdØ—U’U˜1‘X”X‰
ˆˆdØð 	˜Dð 	ØŒt�aŠxˆxØ�S�Ø—’˜RÑ Ô ˆAØ—/’/ "¨¡(Ñ+Ô+ˆCØ—/’/ "¨¡(Ñ+Ô+ˆCØ�c˜3�;ÐñQ(s   ÇG ÇG&Ç%G&c                 óà   — | j         }t          |                      ¦   «         |                     ¦   «         ||j        ¦  «        \  }}|                     |¦  «        |                     |¦  «        fS )z_
    Compute `\frac f g` modulo `p` for two univariate polynomials over
    `\mathbb Z_p`.
    )r   r   Úto_denser   r]   )r   r   r"   r   ÚdensequoÚdenserems         r   Ú_gf_divrÐ   º  sX   € ð
 Œ6€DÝ §
¢
¡¤¨a¯jªj©l¬l¸A¸t¼{ÑKÔKÑ€HˆhØ�?Š?˜8Ñ$Ô$ d§o¢o°hÑ&?Ô&?Ð?Ð?r   c                 ó(  — | j         }|j        }|                     ¦   «         }|dz  }||z
  dz
  }||j        }	}| |j        }}
|
                     ¦   «         |k    rit          ||
|¦  «        d         }|
|||
z  z
                       |¦  «        }
}||	||z  z
                       |¦  «        }}	|
                     ¦   «         |k    °i|
|}}|                     ¦   «         |k    st          |||¦  «        dk    rdS |j        }|dk    rf| 	                    ||¦  «        }| 
                    |¦  «                             |¦  «        }| 
                    |¦  «                             |¦  «        }|                     ¦   «         } ||¦  «         ||¦  «        z  S )a  
    Reconstruct a rational function `\frac a b` in `\mathbb Z_p(t)` from

    .. math::

        c = \frac a b \; \mathrm{mod} \, m,

    where `c` and `m` are polynomials in `\mathbb Z_p[t]` and `m` has
    positive degree.

    The algorithm is based on the Euclidean Algorithm. In general, `m` is
    not irreducible, so it is possible that `b` is not invertible modulo
    `m`. In that case ``None`` is returned.

    Parameters
    ==========

    c : PolyElement
        univariate polynomial in `\mathbb Z[t]`
    p : Integer
        prime number
    m : PolyElement
        modulus, not necessarily irreducible

    Returns
    =======

    frac : FracElement
        either `\frac a b` in `\mathbb Z(t)` or ``None``

    References
    ==========

    1. [Hoeij04]_

    é   r*   r   N)r   r   r   r   r   rÐ   r   r(   r   r   r   Úto_field)Úcr"   rI   r   r   ÚMr¥   ÚDÚr0Ús0Úr1Ús1r^   r~   r˜   Úlcr&   Úfields                     r   Ú!_rational_function_reconstructionrÝ   Ä  s„  € ðJ Œ6€DØŒ[€FØ	�Š‰
Œ
€AØ	ˆQ‰€AØ	ˆA‰�‰	€Aà�”	ˆ€BØ�”ˆ€Bà
�)Š)‰+Œ+˜Š/ˆ/Ý�b˜"˜aÑ Ô  Ô#ˆØ�b˜3˜r™6‘k×/Ò/°Ñ2Ô2ˆBˆØ�b˜3˜r™6‘k×/Ò/°Ñ2Ô2ˆBˆð �)Š)‰+Œ+˜Š/ˆ/ð
 ˆr€q€AØ‡x‚x�z„z�A‚~€~�  A qÑ)Ô)¨QÒ.Ð.Øˆtà	
Œ€BØ	ˆQ‚w€wØ—’˜b !Ñ$Ô$ˆØ�LŠL˜ÑÔ×,Ò,¨QÑ/Ô/ˆØ�LŠL˜ÑÔ×,Ò,¨QÑ/Ô/ˆà�MŠM‰OŒO€Eàˆ5�‰8Œ8�e�e˜A‘h”hÑÐr   c                 ó6  — |j         }|                      ¦   «         D ]|\  }}|dk    rt          |||¦  «        }|s dS nU|j        j         }|                     |¦  «                             ¦   «         D ]!\  }	}
t          |
||¦  «        }|s  dS |||	<   Œ"|||<   Œ}|S )aù  
    Reconstruct every coefficient `c_h` of a polynomial `h` in
    `\mathbb Z_p(t_k)[t_1, \ldots, t_{k-1}][x, z]` from the corresponding
    coefficient `c_{h_m}` of a polynomial `h_m` in
    `\mathbb Z_p[t_1, \ldots, t_k][x, z] \cong \mathbb Z_p[t_k][t_1, \ldots, t_{k-1}][x, z]`
    such that

    .. math::

        c_{h_m} = c_h \; \mathrm{mod} \, m,

    where `m \in \mathbb Z_p[t]`.

    The reconstruction is based on the Euclidean Algorithm. In general, `m`
    is not irreducible, so it is possible that this fails for some
    coefficient. In that case ``None`` is returned.

    Parameters
    ==========

    hm : PolyElement
        polynomial in `\mathbb Z[t_1, \ldots, t_k][x, z]`
    p : Integer
        prime number, modulus of `\mathbb Z_p`
    m : PolyElement
        modulus, polynomial in `\mathbb Z[t]`, not necessarily irreducible
    ring : PolyRing
        `\mathbb Z(t_k)[t_1, \ldots, t_{k-1}][x, z]`, `h` will be an
        element of this ring
    k : Integer
        index of the parameter `t_k` which will be reconstructed

    Returns
    =======

    h : PolyElement
        reconstructed polynomial in
        `\mathbb Z(t_k)[t_1, \ldots, t_{k-1}][x, z]` or ``None``

    See also
    ========

    _rational_function_reconstruction

    r   N)r   rY   rÝ   r   Údrop_to_ground)rK   r"   rI   r   r`   rL   rb   r5   ÚcoeffhÚmonrÔ   rG   s               r   Ú$_rational_reconstruction_func_coeffsrâ     sË   € ð\ 	Œ	€AàŸš™œð ð ‰ˆˆuØ�Š6ˆ6Ý6°u¸aÀÑCÔCˆFàð Ø�t�tðð ”[Ô%ˆFØ×.Ò.¨qÑ1Ô1×;Ò;Ñ=Ô=ð !ð !‘��QÝ6°q¸!¸QÑ?Ô?�àð  Ø˜4˜4˜4à ��s‘�àˆˆ%‰ˆà€Hr   c                 ó
  — | j         }t          |                      ¦   «         |                     ¦   «         ||j        ¦  «        \  }}}|                     |¦  «        |                     |¦  «        |                     |¦  «        fS )zÛ
    Extended Euclidean Algorithm for two univariate polynomials over
    `\mathbb Z_p`.

    Returns polynomials `s, t` and `h`, such that `h` is the GCD of `f` and
    `g` and `sf + tg = h \; \mathrm{mod} \, p`.

    )r   r
   rÍ   r   r]   )r   r   r"   r   ÚsÚtrL   s          r   Ú	_gf_gcdexræ   L  sg   € ð Œ6€DÝ�q—z’z‘|”| Q§Z¢Z¡\¤\°1°d´kÑBÔB�G€A€qˆ!Ø�?Š?˜1ÑÔ˜tŸš¨qÑ1Ô1°4·?²?À1Ñ3EÔ3EÐEÐEr   c                 óÞ   — | j         }|                     |¦  «        }|                     |¦  «        }|                      |¦  «                             ||g¦  «                             |¦  «        S )a  
    Compute the reduced representation of a polynomial `f` in
    `\mathbb Z_p[z] / (\check m_{\alpha}(z))[x]`

    Parameters
    ==========

    f : PolyElement
        polynomial in `\mathbb Z[x, z]`
    minpoly : PolyElement
        polynomial `\check m_{\alpha} \in \mathbb Z[z]`, not necessarily
        irreducible
    p : Integer
        prime number, modulus of `\mathbb Z_p`

    Returns
    =======

    ftrunc : PolyElement
        polynomial in `\mathbb Z[x, z]`, reduced modulo
        `\check m_{\alpha}(z)` and `p`

    )r   r_   Ú
ground_newr   r$   )r   Úminpolyr"   r   Úp_s        r   Ú_truncrë   Z  sa   € ð0 Œ6€DØ×Ò˜tÑ$Ô$€GØ	�Š˜Ñ	Ô	€Bà�>Š>˜!ÑÔ× Ò  '¨2 Ñ/Ô/×<Ò<¸QÑ?Ô?Ð?r   c                 ó„  — | j         }t          | ||¦  «        } t          |||¦  «        }|rÅ| }|                     d¦  «        }t          |                     |¦  «        ||¦  «        \  }}}	|	dk    sdS 	 |                     d¦  «        }
|
|k     rn[||                     |¦  «        z                       |¦  «        }t          ||                     |
|z
  df¦  «        |z  z
  ||¦  «        }Œw|} |}|°Åt          |                     | ¦  «        ||¦  «        d                              |¦  «        }t          | |z  ||¦  «        S )a
  
    Compute the monic GCD of two univariate polynomials in
    `\mathbb{Z}_p[z]/(\check m_{\alpha}(z))[x]` with the Euclidean
    Algorithm.

    In general, `\check m_{\alpha}(z)` is not irreducible, so it is possible
    that some leading coefficient is not invertible modulo
    `\check m_{\alpha}(z)`. In that case ``None`` is returned.

    Parameters
    ==========

    f, g : PolyElement
        polynomials in `\mathbb Z[x, z]`
    minpoly : PolyElement
        polynomial in `\mathbb Z[z]`, not necessarily irreducible
    p : Integer
        prime number, modulus of `\mathbb Z_p`

    Returns
    =======

    h : PolyElement
        GCD of `f` and `g` in `\mathbb Z[z, x]` or ``None``, coefficients
        are in `\left[ -\frac{p-1} 2, \frac{p-1} 2 \right]`

    r   r*   N)r   rë   r   ræ   Údmp_LCr_   r   )r   r   ré   r"   r   r$   r%   r&   Ú_r+   r'   r^   Úlcfinvs                r   Ú_euclidean_algorithmrð   y  sO  € ð8 Œ6€Dåˆq�'˜1ÑÔ€AÝˆq�'˜1ÑÔ€Aà
ð ØˆØ�hŠh�q‰kŒkˆÝ! $§+¢+¨a¡.¤.°'¸1Ñ=Ô=‰ˆˆq�#à�aŠxˆxØ�4ð	OØ—Z’Z ‘]”]ˆFØ˜Š|ˆ|ØØ˜4Ÿ;š; sÑ+Ô+Ñ+×5Ò5°dÑ;Ô;ˆCÝ˜˜qŸ{š{¨F°S©L¸!Ð+<Ñ=Ô=¸cÑAÑAÀ7ÈAÑNÔNˆCð	Oð ˆØˆð! ð õ$ �t—{’{ 1‘~”~ w°Ñ2Ô2°1Ô5×>Ò>¸tÑDÔD€Få�!�f‘*˜g qÑ)Ô)Ð)r   c                 óâ  — | j         }|                     |j        d         |j        d         f¬¦  «        }|                     |¦  «        }| }|                     ¦   «         }|                     ¦   «         }|                     d¦  «        }	t          |¦  «                             |¦  «        }
|j        }|�r9||k    �r2t          |¦  «                             |¦  «        }||
z  |                     ||z
  df¦  «        |z  z
  }|r|                     |¦  «        }|                     d¦  «        }|r¢||	k    rœt          |                     |¦  «        ¦  «                             |¦  «        }| 	                    |¦  «        |                     d||	z
  f¦  «        |z  z
  }|r|                     |¦  «        }|                     d¦  «        }|r||	k    °œ|                     ¦   «         }|r||k    �°2|S )a=  
    Check if `h` divides `f` in
    `\mathbb K[t_1, \ldots, t_k][z]/(m_{\alpha}(z))`, where `\mathbb K` is
    either `\mathbb Q` or `\mathbb Z_p`.

    This algorithm is based on pseudo division and does not use any
    fractions. By default `\mathbb K` is `\mathbb Q`, if a prime number `p`
    is given, `\mathbb Z_p` is chosen instead.

    Parameters
    ==========

    f, h : PolyElement
        polynomials in `\mathbb Z[t_1, \ldots, t_k][x, z]`
    minpoly : PolyElement
        polynomial `m_{\alpha}(z)` in `\mathbb Z[t_1, \ldots, t_k][z]`
    p : Integer or None
        if `p` is given, `\mathbb K` is set to `\mathbb Z_p` instead of
        `\mathbb Q`, default is ``None``

    Returns
    =======

    rem : PolyElement
        remainder of `\frac f h`

    References
    ==========

    .. [1] [Hoeij02]_

    r*   r   rV   )
r   r\   rW   r_   r   rn   r   r   r   r   )r   rL   ré   r"   r   Úzxringr$   r'   r´   ÚdegmÚlchÚlcmÚlcrems                r   Ú_trial_divisionr÷   ±  sÙ  € ðB Œ6€Dà�ZŠZ ¤¨a¤°$´,¸q´/Ð BˆZÑCÔC€Fà×Ò˜tÑ$Ô$€Gà
€Cà�ZŠZ‰\Œ\€FØ�8Š8‰:Œ:€DØ�>Š>˜!ÑÔ€Då
ˆa‰&Œ&�/Š/˜$Ñ
Ô
€CØ
Œ*€Cà
ñ �&˜D’.‘.å�C‘”×!Ò! $Ñ'Ô'ˆØ�#‰g˜Ÿš V¨d¡]°AÐ$6Ñ7Ô7¸Ñ=Ñ=ˆØð 	&Ø×"Ò" 1Ñ%Ô%ˆCØ—’˜A‘”ˆàð 	#�f ’n�nå˜Ÿš VÑ,Ô,Ñ-Ô-×6Ò6°tÑ<Ô<ˆEØ—.’. Ñ%Ô%¨×(9Ò(9¸1¸fÀt¹mÐ:LÑ(MÔ(MÈeÑ(SÑSˆCØð *Ø×&Ò& qÑ)Ô)�Ø—Z’Z ‘]”]ˆFð ð 	#�f ’n�nð —’‘”ˆð! ð �&˜D’.‘.ð$ €Jr   c                 óô   — | j                              | j         j        j                              |¦  «        ¬¦  «        }|j        }|                      ¦   «         D ]\  }}|                     ||¦  «        ||<   Œ|S )z[
    Evaluate a polynomial `f` at `a` in the `i`-th variable of the ground
    domain.
    ©r   )r   r\   r   Údropr   rY   rt   )r   r<   r~   r   r¿   rb   r5   s          r   Ú_evaluate_groundrû   ö  sn   € ð
 Œ6�<Š<˜qœvœ}Ô1×6Ò6°qÑ9Ô9ˆ<Ñ:Ô:€DØ	Œ€BàŸš™œð )ð )‰ˆˆuØ—N’N 1 aÑ(Ô(ˆˆ5‰	ˆ	à€Ir   c           
      ó¢  — | j         }|j        }t          |t          ¦  «        r|j        }nt          | |||¦  «        S |dk    r|j                              ¦   «         }nO|j                              |dz
  ¦  «        }|                     |j        j                              ¦   «         ¬¦  «        }|                     |¬¦  «        }d}	d}
| 	                    | ¦  «        | 	                    |¦  «        z  }|j
        }g }g }g }t          t          |¦  «        ¦  «        }|�r±t          j        |d¦  «        d         }|                     |¦  «         |dk    r!|                     |dz
  |¦  «        |z  dk    }n0|                     |dz
  |¦  «                             |¦  «        dk    }|rŒ�t%          ||dz
  |¦  «        }t%          ||dz
  |¦  «        }|                     ||                      |¦  «        g¦  «        dk    rŒät%          | |dz
  |¦  «        }t%          ||dz
  |¦  «        }t)          ||||¦  «        }|€|
dz  }
|
|	k    rdS �Œ/|dk    r|S |                     ¦   «         gdg|dz
  z  z   }|dk    rX|                     ¦   «         D ]C\  }}|d         |d         k    r,|j        t1          |dd…         ¦  «        k    r|j        |dd…<   ŒD|g}|g}|dk    r|j                             ¦   «         j        }n#|j        j                             ¦   «         j        }|j         j        d         }t9          |||¦  «        D ]>\  }} }!|!|k    r2|                     |¦  «         |                     | ¦  «         |||z
  z  }Œ?|                     |¦  «        }|                     |¦  «         |                     |¦  «         |                     |¦  «         |	dz  }	t=          ||||dz
  |d¬¦  «        }"t?          |"||||dz
  ¦  «        }"|"€�Œï|dk    rˆ|j        j         }#|#j         j        }$|" !                    ¦   «         D ]Z}|#j          "                    tG          |$ $                    ¦   «         |j%         $                    ¦   «         ||#j        ¦  «        ¦  «        }$Œ[n£|j        j        j         }#|#j         j        }$|" !                    ¦   «         D ]q}| !                    ¦   «         D ]Z}%|#j          "                    tG          |$ $                    ¦   «         |%j%         $                    ¦   «         ||#j        ¦  «        ¦  «        }$Œ[Œr| &                    |$                     |¦  «        ¦  «        }$ ||" '                    |$¦  «         (                    ¦   «         ¦  «                             |¦  «        }"tS          | |"||¦  «        stS          ||"||¦  «        s|"S |�°±dS )a—  
    Compute the GCD of two polynomials `f` and `g` in
    `\mathbb Z_p(t_1, \ldots, t_k)[z]/(\check m_\alpha(z))[x]`.

    The algorithm reduces the problem step by step by evaluating the
    polynomials `f` and `g` at `t_k = a` for suitable `a \in \mathbb Z_p`
    and then calls itself recursively to compute the GCD in
    `\mathbb Z_p(t_1, \ldots, t_{k-1})[z]/(\check m_\alpha(z))[x]`. If these
    recursive calls are successful, the GCD over `k` variables is
    interpolated, otherwise the algorithm returns ``None``. After
    interpolation, Rational Function Reconstruction is used to obtain the
    correct coefficients. If this fails, a new evaluation point has to be
    chosen, otherwise the desired polynomial is obtained by clearing
    denominators. The result is verified with a fraction free trial
    division.

    Parameters
    ==========

    f, g : PolyElement
        polynomials in `\mathbb Z[t_1, \ldots, t_k][x, z]`
    minpoly : PolyElement
        polynomial in `\mathbb Z[t_1, \ldots, t_k][z]`, not necessarily
        irreducible
    p : Integer
        prime number, modulus of `\mathbb Z_p`

    Returns
    =======

    h : PolyElement
        primitive associate in `\mathbb Z[t_1, \ldots, t_k][x, z]` of the
        GCD of the polynomials `f` and `g`  or ``None``, coefficients are
        in `\left[ -\frac{p-1} 2, \frac{p-1} 2 \right]`

    References
    ==========

    1. [Hoeij04]_

    r*   rù   r   NT)r•   )*r   r   r�   r   rX   rð   rÓ   rß   r\   rí   r   r¬   r4   r­   r®   r¯   rt   r   rû   r$   Ú_func_field_modgcd_pr   rY   ÚLMÚtupleÚget_ringr   r3   r’   r›   r™   râ   rÜ   Ú
itercoeffsr]   r   rÍ   r—   Ú
domain_newr   Úas_exprr÷   )&r   r   ré   r"   r   r   r`   ÚqdomainÚqringr9   r¼   r,   r}   r“   r½   ÚLMlistr¾   r~   ÚtestÚgammaaÚminpolyar¿   rÀ   rÁ   rþ   rb   r5   Úevalpoints_aÚheval_arI   rå   r˜   ÚhbÚLMhbrL   r#   ÚdenrÔ   s&                                         r   rý   rý     sÊ  € ðT Œ6€DØŒ[€Få�&�.Ñ)Ô)ð 6ØŒLˆˆå# A q¨'°1Ñ5Ô5Ð5àˆA‚v€vØ”+×&Ò&Ñ(Ô(ˆˆà”+×,Ò,¨Q°©UÑ3Ô3ˆØ—-’- w¤~Ô':×'CÒ'CÑ'EÔ'E�-ÑFÔFˆà�JŠJ˜gˆJÑ&Ô&€Eà	€AØ	€Að �KŠK˜‰NŒN˜TŸ[š[¨™^œ^Ñ+€EàŒJ€Eà€JØ€EØ€FÝ•%˜‘(”(‰^Œ^€Fà
ñ ZÝŒM˜& !Ñ$Ô$ QÔ'ˆØ�Š�aÑÔÐà�Š6ˆ6Ø—>’> ! A¡# qÑ)Ô)¨AÑ-°Ò2ˆDˆDà—>’> ! A¡# qÑ)Ô)×6Ò6°qÑ9Ô9¸QÒ>ˆDàð 	Øå! %¨¨1©¨aÑ0Ô0ˆÝ# G¨Q¨q©S°!Ñ4Ô4ˆà�:Š:�x §¢¨Q¡¤Ð0Ñ1Ô1°QÒ6Ð6Øå˜a  1¡ aÑ(Ô(ˆÝ˜a  1¡ aÑ(Ô(ˆõ " " b¨(°AÑ6Ô6ˆàˆ:Ø�‰FˆAØ�1ŠuˆuØ�tÙà�Š7ˆ7ØˆIà�iŠi‰kŒkˆ]˜a˜S ! A¡#™YÑ&ˆØˆqŠ5ˆ5Ø "§¢¡¤ð &ð &‘��uØ˜”8˜r !œuÒ$Ð$¨¬µE¸"¸Q¸R¸R¼&±M´MÒ)AÐ)AØ"œX�B�q�r�r‘Føà�sˆØ�$ˆØ�Š6ˆ6Ø”×%Ò%Ñ'Ô'Ô+ˆAˆAà”Ô#×,Ò,Ñ.Ô.Ô2ˆAàŒFŒK˜ŒNˆå˜z¨5°&Ñ9Ô9ð 	ð 	‰KˆAˆr�4Ø�rŠzˆzØ×#Ò# AÑ&Ô&Ð&Ø—’˜rÑ"Ô"Ð"Ø�a˜!‘e‘�øà�NŠN˜1ÑÔˆØ×Ò˜!ÑÔÐØ�Š�RÑÔÐØ�Š�bÑÔÐØ	ˆQ‰ˆõ & l°G¸TÀ1ÀQÁ3ÈÐRVÐWÑWÔWˆõ 1°°A°q¸%ÀÀ1ÁÑEÔEˆàˆ9Ùà�Š6ˆ6Ø”,Ô$ˆCØ”(”,ˆCàŸš™œð (ð (�Ø”h×)Ò)­&°·²±´ÀÄ×AUÒAUÑAWÔAWØ˜3œ:ñ+'ô +'ñ (ô (��ð(ð
 ”,Ô%Ô+ˆCØ”(”,ˆCàŸš™œð ,ð ,�Ø×)Ò)Ñ+Ô+ð ,ð ,�AØœ(×-Ò-­f°S·\²\±^´^ÀQÄW×EUÒEUÑEWÔEWØ˜sœzñ/+ô /+ñ ,ô ,�C�Cð,ð ×Ò˜s×/Ò/°Ñ2Ô2Ñ3Ô3ˆØˆD�—’˜cÑ"Ô"×*Ò*Ñ,Ô,Ñ-Ô-×:Ò:¸1Ñ=Ô=ˆå˜q ! W¨aÑ0Ô0ð 	½ÈÈAÈwÐXYÑ9ZÔ9Zð 	ØˆHðu ñ Zðx ˆ4r   c                 ó¬  — | dk     r| |z  } ||j         }}| |j        }}t          |dz  ¦  «        }t          |¦  «        |k    r,||z  }||||z  z
  }}||||z  z
  }}t          |¦  «        |k    °,t	          t          |¦  «        ¦  «        |k    rdS |dk     r| | }
}	n|dk    r||}
}	ndS |                     ¦   «         } ||	¦  «         ||
¦  «        z  S )aÌ  
    Reconstruct a rational number `\frac a b` from

    .. math::

        c = \frac a b \; \mathrm{mod} \, m,

    where `c` and `m` are integers.

    The algorithm is based on the Euclidean Algorithm. In general, `m` is
    not a prime number, so it is possible that `b` is not invertible modulo
    `m`. In that case ``None`` is returned.

    Parameters
    ==========

    c : Integer
        `c = \frac a b \; \mathrm{mod} \, m`
    m : Integer
        modulus, not necessarily prime
    domain : IntegerRing
        `a, b, c` are elements of ``domain``

    Returns
    =======

    frac : Rational
        either `\frac a b` in `\mathbb Q` or ``None``

    References
    ==========

    1. [Wang81]_

    r   rÒ   N)r   r   r   ÚintÚabsÚ	get_field)rÔ   rI   r   r×   rØ   rÙ   rÚ   rH   r^   r~   r˜   rÜ   s               r   Ú _integer_rational_reconstructionr  ª  s  € ðH 	ˆ1‚u€uØ	ˆQ‰ˆà�”ˆ€BØ�”
ˆ€Bå��Q‘‰KŒK€Eå
ˆb‰'Œ'�UÒ
Ð
Ø�B‰hˆØ�R˜#˜b™&‘[ˆBˆØ�R˜#˜b™&‘[ˆBˆõ ˆb‰'Œ'�UÒ
Ð
õ
 �3ˆr‰7Œ7�|„|�uÒÐØˆtà	ˆA‚v€vØˆs�R�Cˆ1ˆˆØ	ˆaŠˆØ�2ˆ1ˆˆàˆtà×ÒÑÔ€Eàˆ5�‰8Œ8�e�e˜A‘h”hÑÐr   c                 óø   — |j         }t          |j        t          ¦  «        rt          }|j        j        }nt          }| j        j        }|                      ¦   «         D ]\  }} ||||¦  «        }|s dS |||<   Œ|S )aù  
    Reconstruct every rational coefficient `c_h` of a polynomial `h` in
    `\mathbb Q[t_1, \ldots, t_k][x, z]` from the corresponding integer
    coefficient `c_{h_m}` of a polynomial `h_m` in
    `\mathbb Z[t_1, \ldots, t_k][x, z]` such that

    .. math::

        c_{h_m} = c_h \; \mathrm{mod} \, m,

    where `m \in \mathbb Z`.

    The reconstruction is based on the Euclidean Algorithm. In general,
    `m` is not a prime number, so it is possible that this fails for some
    coefficient. In that case ``None`` is returned.

    Parameters
    ==========

    hm : PolyElement
        polynomial in `\mathbb Z[t_1, \ldots, t_k][x, z]`
    m : Integer
        modulus, not necessarily prime
    ring : PolyRing
        `\mathbb Q[t_1, \ldots, t_k][x, z]`, `h` will be an element of this
        ring

    Returns
    =======

    h : PolyElement
        reconstructed polynomial in `\mathbb Q[t_1, \ldots, t_k][x, z]` or
        ``None``

    See also
    ========

    _integer_rational_reconstruction

    N)r   r�   r   r   Ú#_rational_reconstruction_int_coeffsr   r  rY   )	rK   rI   r   rL   Úreconstructionr   rb   r5   rà   s	            r   r  r  ê  sŒ   € ðR 	Œ	€Aå�$”+�~Ñ.Ô.ð  Ý<ˆØ”Ô!ˆˆå9ˆØ””ˆàŸš™œð ð ‰ˆˆuØ�  q¨&Ñ1Ô1ˆàð 	Ø�4�4àˆˆ%‰ˆà€Hr   c                 ó   — | j         }|j        }t          |t          ¦  «        rP|j        }|j                              |j                             ¦   «         ¬¦  «        }|                     |¬¦  «        }n/d}|                     |j                             ¦   «         ¬¦  «        }|                      ¦   «         \  }} |                     ¦   «         \  }	}|                     | ¦  «        |                     |¦  «        z  }
|j	        }d}g }g }g }	 t          |¦  «        }|
                     |¦  «        dk    rŒ*|dk    r
||z  dk    }n|                     |¦  «        dk    }|rŒV|                      |¦  «        }|                     |¦  «        }|                     |¦  «        }t          ||||¦  «        }|€Œª|dk    r|j        S |                     ¦   «         gdg|z  z   }|dk    rX|                     ¦   «         D ]C\  }}|d         |d         k    r,|j        t#          |dd…         ¦  «        k    r|j        |dd…<   ŒD|}|}t%          |||¦  «        D ]#\  }}}||k    rt'          ||||¦  «        }||z  }Œ$|                     |¦  «         |                     |¦  «         |                     |¦  «         t+          |||¦  «        }|€�Œ¾|dk    r|                     ¦   «         d         }nk|j        j        }|                     ¦   «         D ]5}|j                             ||                     ¦   «         d         ¦  «        }Œ6|                     |¦  «        }|                     |¦  «        }|                     ¦   «         d         }t7          |                      |¦  «        ||¦  «        s&t7          |                     |	¦  «        ||¦  «        s|S �ŒÄ)aí  
    Compute the GCD of two polynomials in
    `\mathbb Q(t_1, \ldots, t_k)[z]/(m_{\alpha}(z))[x]` using a modular
    algorithm.

    The algorithm computes the GCD of two polynomials `f` and `g` by
    calculating the GCD in
    `\mathbb Z_p(t_1, \ldots, t_k)[z] / (\check m_{\alpha}(z))[x]` for
    suitable primes `p` and the primitive associate `\check m_{\alpha}(z)`
    of `m_{\alpha}(z)`. Then the coefficients are reconstructed with the
    Chinese Remainder Theorem and Rational Reconstruction. To compute the
    GCD over `\mathbb Z_p(t_1, \ldots, t_k)[z] / (\check m_{\alpha})[x]`,
    the recursive subroutine ``_func_field_modgcd_p`` is used. To verify the
    result in `\mathbb Q(t_1, \ldots, t_k)[z] / (m_{\alpha}(z))[x]`, a
    fraction free trial division is used.

    Parameters
    ==========

    f, g : PolyElement
        polynomials in `\mathbb Z[t_1, \ldots, t_k][x, z]`
    minpoly : PolyElement
        irreducible polynomial in `\mathbb Z[t_1, \ldots, t_k][z]`

    Returns
    =======

    h : PolyElement
        the primitive associate in `\mathbb Z[t_1, \ldots, t_k][x, z]` of
        the GCD of `f` and `g`

    Examples
    ========

    >>> from sympy.polys.modulargcd import _func_field_modgcd_m
    >>> from sympy.polys import ring, ZZ

    >>> R, x, z = ring('x, z', ZZ)
    >>> minpoly = (z**2 - 2).drop(0)

    >>> f = x**2 + 2*x*z + 2
    >>> g = x + z
    >>> _func_field_modgcd_m(f, g, minpoly)
    x + z

    >>> D, t = ring('t', ZZ)
    >>> R, x, z = ring('x, z', D)
    >>> minpoly = (z**2-3).drop(0)

    >>> f = x**2 + (t + 1)*x*z + 3*t
    >>> g = x*z + 3*t
    >>> _func_field_modgcd_m(f, g, minpoly)
    x + t*z

    References
    ==========

    1. [Hoeij04]_

    See also
    ========

    _func_field_modgcd_p

    rù   r   r*   TN)r   r   r�   r   rX   r\   r  r@   rí   r   r   r   rý   r   r   rY   rþ   rÿ   r’   rŽ   r›   r  Úclear_denomsr  rõ   r   r_   r÷   )r   r   ré   r   r   r`   ÚQQdomainÚQQringrE   rF   r,   r}   r"   ÚprimesÚhplistr  r  r    r!   Úminpolypr-   rþ   rb   r5   rK   rI   r8   r7   ÚLMhqrL   r  s                                  r   Ú_func_field_modgcd_mr  '  s¹  € ðD Œ6€DØŒ[€Få�&�.Ñ)Ô)ð <ØŒLˆØ”;×$Ò$¨F¬M×,CÒ,CÑ,EÔ,EÐ$ÑFÔFˆØ—’ 8�Ñ,Ô,ˆˆàˆØ—’ 4¤;×#8Ò#8Ñ#:Ô#:�Ñ;Ô;ˆà�KŠK‰MŒM�E€BˆØ�KŠK‰MŒM�E€Bˆð �KŠK˜‰NŒN˜TŸ[š[¨™^œ^Ñ+€EàŒJ€Eà	€AØ€FØ€FØ€Fð?Ý�a‰LŒLˆà×Ò˜aÑ Ô  AÒ%Ð%Øà�Š6ˆ6Ø˜A‘I ’NˆDˆDà×&Ò& qÑ)Ô)¨QÒ.ˆDàð 	Øà�^Š^˜AÑÔˆØ�^Š^˜AÑÔˆØ×'Ò'¨Ñ*Ô*ˆå! " b¨(°AÑ6Ô6ˆàˆ:Øà�Š7ˆ7Ø”8ˆOà�iŠi‰kŒkˆ]˜a˜S ™UÑ"ˆØˆqŠ5ˆ5Ø "§¢¡¤ð &ð &‘��uØ˜”8˜r !œuÒ$Ð$¨¬µE¸"¸Q¸R¸R¼&±M´MÒ)AÐ)AØ"œX�B�q�r�r‘FøàˆØˆå˜v v¨vÑ6Ô6ð 	ð 	‰KˆAˆr�4Ø�rŠzˆzÝCÀBÈÈAÈqÑQÔQ�Ø�Q‘�øà�Š�aÑÔÐØ�Š�bÑÔÐØ�Š�bÑÔÐå0°°Q¸Ñ?Ô?ˆàˆ:Ùà�Š6ˆ6Ø—’Ñ!Ô! !Ô$ˆAˆAà”-Ô#ˆCØŸš™œð Fð F�Ø”m×'Ò'¨¨U×-?Ò-?Ñ-AÔ-AÀ!Ô-DÑEÔE��Ø—’˜cÑ"Ô"ˆAð �JŠJ�tÑÔˆØ�KŠK‰MŒM˜!Ôˆå §¢¨RÑ 0Ô 0°!°WÑ=Ô=ð 	Ý˜AŸLšL¨Ñ,Ô,¨a°Ñ9Ô9ð	àˆHñ?r   c                 ó  — |j         }t          |j        t          ¦  «        r|j        j        }n|j        }|j        }|                      ¦   «         D ]6}|                     ¦   «         D ]}|r|                     ||j        ¦  «        }Œ Œ7|  	                    ¦   «         D ]ê\  }}|                     ¦   «         }|j        j        }t          |j        t          ¦  «        r| 
                    |dd…         ¦  «        }t          |¦  «        }	t          |	¦  «        D ]o}
||
         re|                     ||
         |z  ¦  «        |z  }|d         |	|
z
  dz
  f|vr|||d         |	|
z
  dz
  f<   ŒQ||d         |	|
z
  dz
  fxx         |z  cc<   ŒpŒë|S )a‚  
    Compute an associate of a polynomial
    `f \in \mathbb Q(\alpha)[x_0, \ldots, x_{n-1}]` in
    `\mathbb Z[x_1, \ldots, x_{n-1}][z] / (\check m_{\alpha}(z))[x_0]`,
    where `\check m_{\alpha}(z) \in \mathbb Z[z]` is the primitive associate
    of the minimal polynomial `m_{\alpha}(z)` of `\alpha` over
    `\mathbb Q`.

    Parameters
    ==========

    f : PolyElement
        polynomial in `\mathbb Q(\alpha)[x_0, \ldots, x_{n-1}]`
    ring : PolyRing
        `\mathbb Z[x_1, \ldots, x_{n-1}][x_0, z]`

    Returns
    =======

    f_ : PolyElement
        associate of `f` in
        `\mathbb Z[x_1, \ldots, x_{n-1}][x_0, z]`

    r*   Nr   )r   r�   r   r   r   r  Úto_listrõ   ÚdenominatorrY   r   Úlenr4   Úconvert)r   r   Úf_r   r  r5   rÔ   rb   rI   r9   r<   s              r   Ú_to_ZZ_polyr&  Ã  s¨  € ð2 
Œ€Bå�$”+�~Ñ.Ô.ð Ø”Ô#ˆˆà”ˆà
Œ*€Cà—’‘”ð 5ð 5ˆØ—’‘”ð 	5ð 	5ˆAØð 5Ø—j’j  a¤mÑ4Ô4�øð	5ð Ÿš™œð /ð /‰ˆˆuØ—’‘”ˆØŒKŒOˆÝ�d”k¥>Ñ2Ô2ð 	'Ø—’˜E ! " "œIÑ&Ô&ˆAÝ�‰JŒJˆå�q‘”ð 	/ð 	/ˆAØ�QŒxð /Ø—N’N 5¨¤8¨c¡>Ñ2Ô2°QÑ6�à˜!”H˜a ™c !™eÐ$¨BÐ.Ð.Ø,-�B˜˜aœ ! A¡# a¡%Ð(Ñ)Ð)à˜˜aœ ! A¡# a¡%Ð(Ð)Ð)Ô)¨QÑ.Ð)Ð)Ñ)øð	/ð €Ir   c                 ó@  — |j         }|j        }t          | j        j         t          ¦  «        r‡|                      ¦   «         D ]q\  }}|                     ¦   «         D ]W\  }}|d         f|z   } ||                      |¦  «        gdg|d         z  z   ¦  «        }	||vr|	||<   ŒG||xx         |	z  cc<   ŒXŒrni|                      ¦   «         D ]T\  }}|d         f} ||                      |¦  «        gdg|d         z  z   ¦  «        }	||vr|	||<   ŒD||xx         |	z  cc<   ŒU|S )ar  
    Convert a polynomial
    `f \in \mathbb Z[x_1, \ldots, x_{n-1}][z]/(\check m_{\alpha}(z))[x_0]`
    to a polynomial in `\mathbb Q(\alpha)[x_0, \ldots, x_{n-1}]`,
    where `\check m_{\alpha}(z) \in \mathbb Z[z]` is the primitive associate
    of the minimal polynomial `m_{\alpha}(z)` of `\alpha` over
    `\mathbb Q`.

    Parameters
    ==========

    f : PolyElement
        polynomial in `\mathbb Z[x_1, \ldots, x_{n-1}][x_0, z]`
    ring : PolyRing
        `\mathbb Q(\alpha)[x_0, \ldots, x_{n-1}]`

    Returns
    =======

    f_ : PolyElement
        polynomial in `\mathbb Q(\alpha)[x_0, \ldots, x_{n-1}]`

    r   r*   )r   r   r�   r   r   rY   )
r   r   r   r%  rb   r5   rá   ÚcoefrI   rÔ   s
             r   Ú_to_ANP_polyr)  ý  sW  € ð0 Œ[€FØ	Œ€Bå�!”&”-¥Ñ0Ô0ð ØŸKšK™MœMð 	ð 	‰LˆE�5Ø"Ÿ_š_Ñ.Ô.ð ð ‘	��TØ˜1”X�K #Ñ%�Ø�F˜FŸMšM¨$Ñ/Ô/Ð0°A°3°u¸Q´x±<Ñ?Ñ@Ô@�à˜B�;�;Ø�B�q‘E�Eà�q�E�E”E˜Q‘J�E�E‘E�Eðð	ð ŸKšK™MœMð 	ð 	‰LˆE�5Ø�q”�ˆAØ�˜Ÿš eÑ,Ô,Ð-°°°E¸!´H±Ñ<Ñ=Ô=ˆAà˜ˆ{ˆ{Ø��1‘�à�1��”˜‘
��‘�à€Ir   c                 óx   — |j         }|                      ¦   «         D ]\  }}|                     |¦  «        ||<   Œ|S )zo
    Change representation of the minimal polynomial from ``DMP`` to
    ``PolyElement`` for a given ring.
    )r   Útermsr   )ré   r   Úminpoly_rb   r5   s        r   Ú_minpoly_from_denser-  0  sB   € ð
 Œy€HàŸš™œð -ð -‰ˆˆuØŸ+š+ eÑ,Ô,ˆ�‰ˆà€Or   c                 óz  — | j         } |j        t          d|j        ¦  «        Ž }|j        j         } ||                      ¦   «         ¦  «        }|j        }|                     ¦   «         D ])}t          ||¦  «        d         }||j	        k    r|| fc S Œ*||  
                    |                     |¦  «        ¦  «        fS )z¿
    Compute the content in `x_0` and the primitive part of a polynomial `f`
    in
    `\mathbb Q(\alpha)[x_0, x_1, \ldots, x_{n-1}] \cong \mathbb Q(\alpha)[x_1, \ldots, x_{n-1}][x_0]`.
    r*   r   )r   rß   r4   rX   r   r  r   r  Úfunc_field_modgcdr   r^   r_   )r   Úfringr   r#   r%  rc   r5   s          r   Ú_primitive_in_x0r1  =  s»   € ð ŒF€EØˆ5Ô¥ q¨%¬+Ñ!6Ô!6Ð7€DØ
Œ+Ô
€CØ	ˆˆa�iŠi‰kŒkÑ	Ô	€BØŒ8€Dà—’‘”ð ð ˆÝ   uÑ-Ô-¨aÔ0ˆØ�3”7Š?ˆ?Ø˜�7ˆNˆNˆNð ð �—’�t—}’} UÑ+Ô+Ñ,Ô,Ð,Ð,r   c                 óÌ  — | j         }|j        }|j        }||j         k    r|j        sJ ‚t	          | |¦  «        }|�|S t          d¦  «        }|                     |j        |fz   |j                             ¦   «         ¬¦  «        }|dk    r‚t          | |¦  «        }t          ||¦  «        }	| 
                    d¦  «                             |j                             ¦   «         ¦  «        }
t          ||	|
¦  «        }t          ||¦  «        }�nt!          | ¦  «        \  }} t!          |¦  «        \  }}t#          ||¦  «        d         } |j        t'          d|¦  «        Ž }t          | |¦  «        }t          ||¦  «        }	t)          |j        | 
                    d¦  «        ¦  «        }
t          ||	|
¦  «        }t          ||¦  «        }t!          |¦  «        \  }}||                     |¦  «        z  }| |                     |¦  «        z  } ||                     |¦  «        z  }|                     |j        ¦  «        }||                      |¦  «        |                     |¦  «        fS )a  
    Compute the GCD of two polynomials `f` and `g` in
    `\mathbb Q(\alpha)[x_0, \ldots, x_{n-1}]` using a modular algorithm.

    The algorithm first computes the primitive associate
    `\check m_{\alpha}(z)` of the minimal polynomial `m_{\alpha}` in
    `\mathbb{Z}[z]` and the primitive associates of `f` and `g` in
    `\mathbb{Z}[x_1, \ldots, x_{n-1}][z]/(\check m_{\alpha})[x_0]`. Then it
    computes the GCD in
    `\mathbb Q(x_1, \ldots, x_{n-1})[z]/(m_{\alpha}(z))[x_0]`.
    This is done by calculating the GCD in
    `\mathbb{Z}_p(x_1, \ldots, x_{n-1})[z]/(\check m_{\alpha}(z))[x_0]` for
    suitable primes `p` and then reconstructing the coefficients with the
    Chinese Remainder Theorem and Rational Reconstruction. The GCD over
    `\mathbb{Z}_p(x_1, \ldots, x_{n-1})[z]/(\check m_{\alpha}(z))[x_0]` is
    computed with a recursive subroutine, which evaluates the polynomials at
    `x_{n-1} = a` for suitable evaluation points `a \in \mathbb Z_p` and
    then calls itself recursively until the ground domain does no longer
    contain any parameters. For
    `\mathbb{Z}_p[z]/(\check m_{\alpha}(z))[x_0]` the Euclidean Algorithm is
    used. The results of those recursive calls are then interpolated and
    Rational Function Reconstruction is used to obtain the correct
    coefficients. The results, both in
    `\mathbb Q(x_1, \ldots, x_{n-1})[z]/(m_{\alpha}(z))[x_0]` and
    `\mathbb{Z}_p(x_1, \ldots, x_{n-1})[z]/(\check m_{\alpha}(z))[x_0]`, are
    verified by a fraction free trial division.

    Apart from the above GCD computation some GCDs in
    `\mathbb Q(\alpha)[x_1, \ldots, x_{n-1}]` have to be calculated,
    because treating the polynomials as univariate ones can result in
    a spurious content of the GCD. For this ``func_field_modgcd`` is
    called recursively.

    Parameters
    ==========

    f, g : PolyElement
        polynomials in `\mathbb Q(\alpha)[x_0, \ldots, x_{n-1}]`

    Returns
    =======

    h : PolyElement
        monic GCD of the polynomials `f` and `g`
    cff : PolyElement
        cofactor of `f`, i.e. `\frac f h`
    cfg : PolyElement
        cofactor of `g`, i.e. `\frac g h`

    Examples
    ========

    >>> from sympy.polys.modulargcd import func_field_modgcd
    >>> from sympy.polys import AlgebraicField, QQ, ring
    >>> from sympy import sqrt

    >>> A = AlgebraicField(QQ, sqrt(2))
    >>> R, x = ring('x', A)

    >>> f = x**2 - 2
    >>> g = x + sqrt(2)

    >>> h, cff, cfg = func_field_modgcd(f, g)

    >>> h == x + sqrt(2)
    True
    >>> cff * h == f
    True
    >>> cfg * h == g
    True

    >>> R, x, y = ring('x, y', A)

    >>> f = x**2 + 2*sqrt(2)*x*y + 2*y**2
    >>> g = x + sqrt(2)*y

    >>> h, cff, cfg = func_field_modgcd(f, g)

    >>> h == x + sqrt(2)*y
    True
    >>> cff * h == f
    True
    >>> cfg * h == g
    True

    >>> f = x + sqrt(2)*y
    >>> g = x + y

    >>> h, cff, cfg = func_field_modgcd(f, g)

    >>> h == R.one
    True
    >>> cff * h == f
    True
    >>> cfg * h == g
    True

    References
    ==========

    1. [Hoeij04]_

    NÚz)rW   r   r*   r   )r   r   rX   Úis_Algebraicr   r   r\   rW   r   r&  rú   r]   Úmodr!  r  r)  r1  r/  rß   r4   r-  r_   rA   r   r^   )r   r   r   r   r9   rD   r3  ÚZZringr%  Úg_ré   rL   Úcontx0fÚcontx0gÚcontx0hÚZZring_Úcontx0h_s                    r   r/  r/  R  s+  € ðP Œ6€DØŒ[€FØŒ
€Aà�1”6Š>ˆ>˜fÔ1ˆ>ˆ>Ð1å˜!˜QÑÔ€FØÐØˆåˆc‰
Œ
€Aà�ZŠZ ¤°¨tÑ 3¸F¼M×<RÒ<RÑ<TÔ<TˆZÑUÔU€FàˆA‚v€vÝ˜˜FÑ#Ô#ˆÝ˜˜FÑ#Ô#ˆØ—+’+˜a‘.”.×+Ò+¨F¬J×,>Ò,>Ñ,@Ô,@ÑAÔAˆå   R¨Ñ1Ô1ˆÝ˜˜DÑ!Ô!ˆ‰õ & aÑ(Ô(‰
ˆ�Ý% aÑ(Ô(‰
ˆ�Ý# G¨WÑ5Ô5°aÔ8ˆà'�&Ô'­¨q°!©¬Ð5ˆå˜˜GÑ$Ô$ˆÝ˜˜GÑ$Ô$ˆÝ% f¤j°'·,²,¸q±/´/ÑBÔBˆå   R¨Ñ1Ô1ˆÝ˜˜DÑ!Ô!ˆå& qÑ)Ô)‰ˆ�!Ø	ˆW×Ò˜dÑ#Ô#Ñ#ˆØ	ˆW×Ò˜dÑ#Ô#Ñ#ˆØ	ˆW×Ò˜dÑ#Ô#Ñ#ˆà	�Š�Q”TÑÔ€Aàˆa�eŠe�A‰hŒh˜Ÿš˜a™œÐ Ð r   )F)N)3Úsympy.core.symbolr   Úsympy.ntheoryr   Úsympy.ntheory.modularr   Úsympy.polys.domainsr   Úsympy.polys.galoistoolsr   r	   r
   r   r   Úsympy.polys.polyerrorsr   Úmpmathr   r­   r   r(   r/   r=   rS   rf   rj   rn   rr   rƒ   rŽ   r™   rª   r°   rË   rÐ   rÝ   râ   ræ   rë   rð   r÷   rû   rý   r  r  r  r&  r)  r-  r1  r/  rÅ   r   r   ú<module>rD     s÷  ðØ #Ð #Ð #Ð #Ð #Ð #Ø #Ð #Ð #Ð #Ð #Ð #Ø %Ð %Ð %Ð %Ð %Ð %Ø .Ð .Ð .Ð .Ð .Ð .ð4ð 4ð 4ð 4ð 4ð 4ð 4ð 4ð 4ð 4ð 4ð 4ð 4ð 4à 3Ð 3Ð 3Ð 3Ð 3Ð 3à Ð Ð Ð Ð Ð Ø €€€ðð ð ð,?ð ?ð ?ð.ð ð ðB>ð >ð >ðB~ð ~ð ~ðB:.ð :.ð :.ðz-ð -ð -ð`2ð 2ð 2ðj	ð 	ð 	ðH5ð H5ð H5ðV`ð `ð `ðF>ð >ð >ð >ðBQð Qð QðhVð Vð VðrPð Pð Pðf@ð @ð @ð?ð ?ð ?ðDCð Cð CðLFð Fð Fð@ð @ð @ð>5*ð 5*ð 5*ðpBð Bð Bð BðJð ð ðcð cð cðL=ð =ð =ð@:ð :ð :ðzYð Yð Yðx7ð 7ð 7ðt0ð 0ð 0ðf
ð 
ð 
ð-ð -ð -ð*T!ð T!ð T!ð T!ð T!r   