+
    ‹°³jiå  ã                   ó:  € ^ RI Ht ^ RIHt ^ RIHt ^ RIHt ^ RIH	t	H
t
HtHtHt ^ RIHt ^ RIHt ^ RItR	 tR
 tR tR tR tR tR tR tR tR tR tR)R ltR tR t R t!R t"R t#R t$R t%R t&R t'R*R lt(R t)R  t*R! t+R" t,R# t-R$ t.R% t/R& t0R' t1R( t2R# )+é    )ÚDummy)Ú	nextprime©Úcrt)ÚPolynomialRing)Úgf_gcdÚgf_from_dictÚgf_gcdexÚgf_divÚgf_lcm)ÚModularGCDFailed)ÚsqrtNc                ó  € V P                   pV '       g,   V'       g$   VP                  VP                  VP                  3# V '       gY   VP                  VP                  P                  8  d   V) VP                  VP                  ) 3# WP                  VP                  3# V'       gY   V P                  VP                  P                  8  d   V ) VP                  ) VP                  3# WP                  VP                  3# R# )zb
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   && ÚW/home/luca/screen-checking/.venv/lib/python3.14/site-packages/sympy/polys/modulargcd.pyÚ_trivial_gcdr      s¸   € ð
 �6‰6€Dç—Ø�y‰y˜$Ÿ)™) T§Y¡YÐ.Ð.ßØ�4‰4�$—+‘+×"Ñ"Ô"Ø�2�t—y‘y 4§8¡8 )Ð+Ð+à—i‘i §¡Ð)Ð)ßØ�4‰4�$—+‘+×"Ñ"Ô"Ø�2˜Ÿ™�y $§)¡)Ð+Ð+à—h‘h §	¡	Ð)Ð)Ùó    c                óæ  € V P                   P                  pV'       d›   T pVP                  4       pVP                  VP                  V4      p VP                  4       pWu8  d   MNWAP                  Wu,
          34      P                  WdP                  ,          4      ,
          P                  V4      pKf  Tp TpK¢  V P                  VP                  V P                  V4      4      P                  V4      # )zE
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ˆØ—
‘
˜2Ÿ5™5 !Ó$ˆàØ—Z‘Z“\ˆFØŒ|ØØŸ™ v¥| oÓ6×AÑAÀ%Ï&É&Å.ÓQÕQ×_Ñ_Ð`aÓbŠCàˆØŠà�=‰=˜Ÿ™ B§E¡E¨1Ó-Ó.×;Ñ;¸AÓ>Ð>r   c                óD  € V P                   P                  P                  V P                  VP                  4      p^p\	        V4      pW#,          ^ 8X  d   \	        V4      pK  V P                  V4      pVP                  V4      p\        WEV4      pVP                  4       pV# )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   Úgcdr   r   r   r(   r   )r   r   Úgammar"   r    r!   ÚhpÚdeghps   &&      r   Ú_degree_bound_univariater.   :   s~   € ð& �F‰F�M‰M×Ñ˜aŸd™d A§D¡DÓ)€EØ	€Aä�!‹€AØ
�)�qŒ.Ü�a‹LŠà	
�‰˜Ó	€BØ	
�‰˜Ó	€BÜ	�˜Ó	€BØ�I‰I‹K€EØ€Lr   c           	     óh  € V P                  4       pV P                  P                  ^ ,          pV P                  P                  p\	        V^,           4       FH  p\        W#.V P                  WW,          4      VP                  WW,          4      .RR7      ^ ,          Wg3&   KJ  	  VP                  4        V# )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

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ˆÜ˜˜ §¡¨!­$£°·±¸!½$³Ð @ÈDÔQÐRSÕTˆˆD‹	ñ ð ‡N�NÔØ€Jr   c                ó*  € V P                   VP                   8X  d'   V P                   P                  P                  '       g   Q h\        W4      pVe   V# V P                   pV P	                  4       w  r@VP	                  4       w  rQVP                  P                  WE4      p\        W4      pV^ 8X  d6   V! V4      V P                  WF,          4      VP                  WV,          4      3# VP                  P                  V P                  VP                  4      p^p	^p
 \        V
4      p
WŠ,          ^ 8X  d   \        V
4      p
K  V P                  V
4      pVP                  V
4      p\        W¼V
4      pVP                  4       pWç8”  d   Kl  Wç8  d   ^p	TpKx  VP                  V4      P                  V
4      pV	^8X  d   T
p	TpK¥  \        VXW©4      pWš,          p	VV8X  g   TpKÅ  VP                  VP                  4       4      pV P!                  V4      w  ppVP!                  V4      w  ppV'       d   EK  V'       d   EK"  VP                  ^ 8  d   V) pVP                  V4      pVP                  WF,          4      pVP                  WV,          4      pVVV3# )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]_

)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_univariaterR   œ   s  € ðF �6‰6�Q—V‘VÔ §¡§¡× 3× 3Ð 3Ð3Ð3ä˜!Ó€FØÒØˆà�6‰6€Dà�K‰K‹M�E€BØ�K‰K‹M�E€BØ	�‰�‰˜Ó	 €Bä$ QÓ*€EØ�„zÙ�B‹x˜Ÿ™ b¥hÓ/°·±¸b½hÓ1GÐGÐGà�K‰K�O‰O˜AŸD™D !§$¡$Ó'€EØ	€AØ	€Aà
Ü�a‹LˆØ�i˜1ŒnÜ˜!“ŠAà�^‰^˜AÓˆØ�^‰^˜AÓˆÜ�R˜QÓˆØ—	‘	“ˆàŒ=ÙØŒ]ØˆAØˆEÙà�]‰]˜5Ó!×.Ñ.¨qÓ1ˆØ�Œ6ØˆAØˆFÙä9¸"¸fÀaÓKˆØ	�ˆà�VŒ|ØˆFÙà�M‰M˜"Ÿ*™*›,Ó'ˆØ—U‘U˜1“X‰
ˆˆdØ—U‘U˜1“X‰
ˆˆdßŠtŸDšDØ�t‰t�aŒxØ�S�Ø—‘˜RÓ ˆAØ—/‘/ "¥(Ó+ˆCØ—/‘/ "¥(Ó+ˆCØ�c˜3�;Ðr   c           	     ó  € V P                   pVP                  pVP                  p/ pV P                  4        F+  w  rgVRR V9  d   / WVRR &   WuVRR ,          VR,          &   K-  	  . p\	        VP                  4       4       F  p\        V\        WqV4      W4      pK  	  VP                  VP                  V^,
          ,          R7      p	V	P                  V4      P                  V4      p
W P                  V
P                  V4      4      3# )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©Úsymbolséÿÿÿÿ)r   r   ÚngensÚ	itertermsÚiterÚvaluesr   r	   ÚclonerU   Ú
from_denser   ÚquoÚset_ring)r   r"   r   r#   ÚkÚcoeffsÚmonomr4   ÚcontÚyringÚcontfs   &&         r   Ú
_primitivere     sð   € ðR �6‰6€DØ
�+‰+€CØ�
‰
€Aà€FØŸ™ž‰ˆØ��"ˆ:˜VÔ#Ø!#ˆF˜˜"�:ÑØ(-ˆu�S�bˆzÕ˜5 �9Ó%ñ &ð
 €DÜ�f—m‘m“oÖ&ˆÜ�dœL¨°3Ó7¸Ó@Šñ 'ð �J‰J˜tŸ|™|¨A¨a­CÕ0ˆJÓ1€EØ×Ñ˜TÓ"×/Ñ/°Ó2€Eà—%‘%˜Ÿ™ tÓ,Ó-Ð-Ð-r   c                ó¢   € V P                   P                  pRV^,
          ,          pV P                  4        F  pVRR V8”  g   K  VRR pK  	  V# )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)

N)r   rV   )r   rW   Ú
itermonoms)r   r_   Údegfra   s   &   r   Ú_degri   Z  sO   € ðP 	
�‰�‰€AØ�1�Q•3�<€DØ—‘–ˆØ��"ˆ:˜ÖØ˜˜"�:ŠDñ  ð €Kr   c                ó`  € V P                   pVP                  pVP                  VP                  V^,
          ,          R7      pVP                  ^ ,          p\        V 4      pVP                  pV P                  4        F-  w  rxVRR V8X  g   K  WhWGR,          ,          ,          ,          pK/  	  V# )ag  
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

rT   NrV   )r   rW   r[   rU   r2   ri   r   rX   )	r   r   r_   rc   Úyrh   Úlcfra   r4   s	   &        r   Ú_LCrm   Š  s�   € ðP �6‰6€DØ�
‰
€AØ�J‰J˜tŸ|™|¨A¨a­CÕ0ˆJÓ1€EØ�
‰
�1�€AÜ�‹7€Dà
�*‰*€CØŸ™ž‰ˆØ��"ˆ:˜ÖØ˜ "�I�Õ%Õ%ŠCñ &ð €Jr   c                ó¶   € V P                   pVP                  pV P                  4        F,  w  rEWA,          3VRV ,           WA^,           R ,           pWSV&   K.  	  V# )zK
Make the variable `x_i` the leading one in a multivariate polynomial `f`.
N)r   r   rX   )r   r;   r   Úfswapra   r4   Ú	monomswaps   &&     r   Ú_swaprq   ¿  sX   € ð �6‰6€DØ�I‰I€EØŸ™ž‰ˆØ•X�K %¨¨ )Õ+¨e°aµC°D¨kÕ9ˆ	Ø ˆiÓñ &ð €Lr   c                óÎ  € V P                   pVP                  P                  V P                  VP                  4      pVP                  P                  \	        V ^4      P                  \	        V^4      P                  4      pW4,          p^p\        V4      pWV,          ^ 8X  d   \        V4      pK  V P                  V4      pVP                  V4      p\        Wv4      w  r—\        W†4      w  r¨\        WšV4      pVP                  4       p\        \        V4      \        V4      V4      p\        V4       F‡  pVP                  ^ V4      V,          '       g   K$  VP                  ^V4      P                  V4      pVP                  ^V4      P                  V4      p\        VVV4      pVP                  4       pVV3u # 	  \        VP                  4       VP                  4       4      V3# )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   rq   r   r   re   r(   r   rm   r3   Ú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‰6€Dà�[‰[�_‰_˜QŸT™T 1§4¡4Ó(€FØ�[‰[�_‰_œU 1 a›[Ÿ^™^¬U°1°a«[¯^©^Ó<€FØ•€IØ	€Aä�!‹€AØ
�-˜1Ô
Ü�a‹LŠà	
�‰˜Ó	€BØ	
�‰˜Ó	€BÜ˜BÓ"�J€FÜ˜BÓ"�J€FÜ�V QÓ'€FØ—‘“€Jô ”C˜“GœS ›W aÓ(€Eä�1ŽXˆØ�~‰~˜a Ó# a×'Ô'ÙØ�k‰k˜!˜QÓ×,Ñ,¨QÓ/ˆØ�k‰k˜!˜QÓ×,Ñ,¨QÓ/ˆÜ�c˜3 Ó"ˆØ—‘“ˆØ�zÐ!Ò!ñ ô ˆr�y‰y‹{˜BŸI™I›KÓ(¨*Ð4Ð4r   c                ó^  a€ \        V P                  4       4      p\        VP                  4       4      pVP                  V4      pVP                  V4       VP                  V4       V P                  P
                  oSP                  pV P                  P                  p\        V P                  P
                  \        4      '       d   \        p	MV3R lp	V F  p
V	! W
,          W,          W#4      WŠ&   K  	  V F  p
V	! W
,          WrV4      WŠ&   K  	  V F  p
V	! WqV
,          W#4      WŠ&   K  	  V# )aj  
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                 ó>   <€ S! \        W#.W.R R7      ^ ,          4      # )Tr0   r   )ÚcpÚcqr"   r7   r   s   &&&&€r   Úcrt_Ú<_chinese_remainder_reconstruction_multivariate.<locals>.crt_l  s    ø€ Ùœ#˜q˜f r h¸$Ô?ÀÕBÓCÐCr   )
ÚsetÚmonomsÚintersectionÚdifference_updater   r   r   Ú
isinstancer   Ú._chinese_remainder_reconstruction_multivariate)r,   r6   r"   r7   ÚhpmonomsÚhqmonomsrŠ   r   r:   r‡   ra   r   s   &&&&       @r   rŽ   rŽ     sô   ø€ ôP �2—9‘9“;Ó€HÜ�2—9‘9“;Ó€HØ×"Ñ" 8Ó,€FØ×Ñ˜vÔ&Ø×Ñ˜vÔ&à�W‰W�^‰^€FØ�;‰;€Dà
�'‰'�,‰,€Cä�"—'‘'—.‘.¤.×1Ò1Ü=‰õ	Dó ˆÙ˜"�) R¥Y°Ó5ˆ‹
ñ ãˆÙ˜"�) T¨aÓ0ˆ‹
ñ ãˆÙ˜$ 5¥	¨1Ó0ˆ‹
ñ ð €Jr   c                ó(  € VP                   pV'       d5   VP                  P                  pVP                  P                  V,          pMVP                  pVP                  V,          p\        W4       FŒ  w  ršVP                  pVP                  pV  F)  pWÙ8X  d   K  W¸V,
          ,          pWÉV,
          ,          pK+  	  VP                  WÄ4      pVP                  V4      pWjP                  V4      V,          ,          pKŽ  	  VP                  V4      # )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   r2   Úzipr   r   r   r^   r   )Ú
evalpointsÚhpevalr   r;   r"   Úgroundr,   r   rk   r}   r€   ÚnumerÚdenomÚbr4   s   &&&&&&         r   Ú_interpolate_multivariater™   y  sÜ   € ðN 
�‰€BçØ—‘×#Ñ#ˆØ�K‰K×Ñ˜QÕ‰à—‘ˆØ�I‰I�a�Lˆä�jÖ)‰ˆØ—‘ˆØ—
‘
ˆÛˆAØŒvÙà˜•U�NˆEØ˜•U�NŠEñ ð —‘˜eÓ'ˆØ× Ñ  Ó'ˆØ
�l‰l˜4Ó  5Õ(Õ(Šñ *ð �?‰?˜1ÓÐr   c                ó&  € V P                   VP                   8X  d'   V P                   P                  P                  '       g   Q h\        W4      pVe   V# V P                   pV P	                  4       w  r@VP	                  4       w  rQVP                  P                  WE4      p\        W4      w  rxYxu;8X  d   ^ 8X  d9   M M5V! V4      V P                  WF,          4      VP                  WV,          4      3# \        V ^4      p	\        V^4      p
V	P                  4       pV
P                  4       p\        Wš4      w  rÞYÞu;8X  d   ^ 8X  d9   M M5V! V4      V P                  WF,          4      VP                  WV,          4      3# VP                  P                  V P                  VP                  4      pVP                  P                  V	P                  V
P                  4      pVV,          p^p^p \        V4      pVV,          ^ 8X  d   \        V4      pK  V P                  V4      pVP                  V4      p\        VV4      w  pp\        VV4      w  pp\        VVV4      pVP                  4       pVV8”  d   K�  VV8  d   ^pTpKš  \        \        V4      \        V4      V4      pVP                  4       pVP                  4       pVP                  4       p\!        VV,
          VV,
          WØ,
          V,           4      ^,           pVV8  d   EK"  ^ p. p . p!Rp"\#        V4       Fñ  p#VP%                  ^ V#4      p$V$V,          '       g   K&  VP%                  ^V#4      P                  V4      p%VP%                  ^V#4      P                  V4      p&\        V%V&V4      p'V'P                  4       p(V(V8”  d   KŽ  V(V8  d	   ^pT(pRp" MXV'P                  V$4      P                  V4      p'V P'                  V#4       V!P'                  V'4       V^,          pVV8X  g   Kñ   M	  V"'       d   EK5  VV8  d   EK?  \)        V V!V^V4      p)\        V)V4      ^,          p)V)VP+                  V4      ,          p)V)P                  ^4      p*V*V8”  d   EK”  V*V8  d   ^pT*pEK¢  V)P                  V4      P                  V4      p)V^8X  d   TpT)p+EKÐ  \-        V)X+VV4      p,VV,          pV,V+8X  g   T,p+EKó  V,P/                  V,P1                  4       4      p-V P3                  V-4      w  p.p/VP3                  V-4      w  p0p1V/'       d   EKE  V1'       d   EKP  V-P                  ^ 8  d   V) pV-P                  V4      p-V.P                  WF,          4      p2V0P                  WV,          4      p3V-V2V33# )aI  
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]_

TF)r   r   r>   r   r?   r*   r‚   r   rq   r   r   r   r   re   r(   rm   rt   r3   rs   Úappendr™   r^   rŽ   r@   rA   rB   )4r   r   rC   r   rD   rE   rF   r�   r{   ro   ÚgswapÚdegyfÚdegygÚyboundÚ
xcontboundru   rv   rw   rH   r"   r    r!   rx   ry   rz   Ú	degconthpr|   Ú	degcontfpÚ	degcontgpÚdegdeltaÚNr8   r“   r”   Úunluckyr}   Údeltaar~   r   r€   Údeghpar,   ÚdegyhprI   rJ   rK   rL   rM   rN   rO   rP   rQ   s4   &&                                                  r   Úmodgcd_bivariaterª   º  s¾  € ðR �6‰6�Q—V‘VÔ §¡§¡× 3× 3Ð 3Ð3Ð3ä˜!Ó€FØÒØˆà�6‰6€Dà�K‰K‹M�E€BØ�K‰K‹M�E€BØ	�‰�‰˜Ó	 €Bä0°Ó6Ñ€FØÖ ˜q× Ù�B‹x˜Ÿ™ b¥hÓ/°·±¸b½hÓ1GÐGÐGä�!�Q‹K€EÜ�!�Q‹K€EØ�L‰L‹N€EØ�L‰L‹N€Eä0°Ó>Ñ€FØÖ ˜q× Ù�B‹x˜Ÿ™ b¥hÓ/°·±¸b½hÓ1GÐGÐGð �[‰[�_‰_˜QŸT™T 1§4¡4Ó(€FØ�[‰[�_‰_˜UŸX™X u§x¡xÓ0€FØ˜•€IØ	€AØ	€Aà
Ü�a‹LˆØ˜!�m˜qÔ Ü˜!“ŠAà�^‰^˜AÓˆØ�^‰^˜AÓˆÜ  AÓ&‰
ˆ�Ü  AÓ&‰
ˆ�Ü˜ ¨Ó+ˆØ—M‘M“Oˆ	à�zÔ!ÙØ˜Ô#ØˆAØ"ˆJÙô œ˜B›¤ R£¨!Ó,ˆà—M‘M“Oˆ	Ø—M‘M“Oˆ	Ø—<‘<“>ˆä�˜	Õ! 5¨9Õ#4ØÕ (Õ*ó,Ø./õ0ˆð ˆqŒ5ÚàˆØˆ
ØˆØˆä�q–ˆAØ—^‘^ A qÓ)ˆFØ˜A—:”:Ùà—+‘+˜a Ó#×0Ñ0°Ó3ˆCØ—+‘+˜a Ó#×0Ñ0°Ó3ˆCÜ˜#˜s AÓ&ˆCØ—Z‘Z“\ˆFà˜ŒÙØ˜&”Ø�Ø�Ø�Ùà—.‘. Ó(×5Ñ5°aÓ8ˆCØ×Ñ˜aÔ Ø�M‰M˜#ÔØ��FˆAà�AŽvÙñ1 ÷4 ÚØˆqŒ5Úä& z°6¸4ÀÀAÓFˆä˜˜AÓ˜qÕ!ˆØ�&—/‘/ $Ó'Õ'ˆØ—‘˜1“ˆà�FŒ?ÚØ�FŒ?ØˆAØˆFÚà�]‰]˜6Ó"×/Ñ/°Ó2ˆØ�Œ6ØˆAØˆFÚä;¸BÀÈÈ1ÓMˆØ	ˆQ�ˆà�VŒ|ØˆFÚà�M‰M˜"Ÿ*™*›,Ó'ˆØ—U‘U˜1“X‰
ˆˆdØ—U‘U˜1“X‰
ˆˆdßŠtŸDšDØ�t‰t�aŒxØ�S�Ø—‘˜RÓ ˆAØ—/‘/ "¥(Ó+ˆCØ—/‘/ "¥(Ó+ˆCØ�c˜3�;Ðr   c                ó\  € V P                   pVP                  pV^8X  dT   \        WV4      P                  V4      pVP	                  4       pWƒ^ ,          8”  d   R# Wƒ^ ,          8  d   Wƒ^ &   \
        hV# V P	                  V^,
          4      p	VP	                  V^,
          4      p
\        W4      w  r°\        W4      w  rÁ\        W¼V4      pVP	                  4       pVP	                  4       pVP	                  4       pVWF^,
          ,          8”  d   R# VWF^,
          ,          8  d   VWF^,
          &   \
        h\        V 4      p\        V4      p\        VVV4      pTp\        V^,
          4       F=  pV\        \        \        V V4      4      \        \        VV4      4      V4      ,          pK?  	  VP	                  4       p\        Wž,
          W¯,
          W6^,
          ,          WF^,
          ,          ,
          V,           4      ^,           pVV8  d   R# ^ p^ p. p. p\        \        V4      4      pV'       Edû   \        P                  ! V^4      ^ ,          pVP                  V4       VP                  ^ V4      V,          '       g   KY  VP                  ^ V4      V,          pV P                  V^,
          V4      P                  V4      pVP                  V^,
          V4      P                  V4      p \!        VV W#V4      p!V!f   V^,          pVV8”  d   R# Kè  V!P"                  '       d#   VP%                  V4      P                  V4      pV# V!P'                  V4      P                  V4      p!VP)                  V4       VP)                  V!4       V^,          pVV8X  g   EKq  \+        VVWV^,
          V4      p\        Wr4      ^,          VP%                  V4      ,          pVP	                  V^,
          4      p"V"W6^,
          ,          8”  d   R# V"W6^,
          ,          8  d   V"W6^,
          &   \
        hV# R# )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]_

N)r   rW   r(   r   r   r   re   rm   r3   rq   rt   ÚlistÚrandomÚsampleÚremovers   Ú_modgcd_multivariate_pÚ	is_groundr^   r   r›   r™   )#r   r   r"   ÚdegboundÚ	contboundr   r_   rK   Údeghr�   rž   rd   ÚcontgÚconthÚdegcontfÚdegcontgÚdegconthrl   Úlcgr|   Úevaltestr;   r¤   r¥   r8   Údr“   ÚhevalÚpointsr}   r§   ÚfaÚgaÚhaÚdegyhs#   &&&&&                              r   r°   r°   Ž  st  € ð` �6‰6€DØ�
‰
€AàˆA„vÜ�A˜!Ó×)Ñ)¨!Ó,ˆØ�x‰x‹zˆà˜1•+ÔÙØ˜1•+ÔØ�Q‰KÜ"Ð"àˆà�H‰H�Q�q•S‹M€EØ�H‰H�Q�q•S‹M€Eä˜!Ó�H€EÜ˜!Ó�H€Eä�E !Ó$€Eà�|‰|‹~€HØ�|‰|‹~€HØ�|‰|‹~€Hà�)˜a�C•.Ô ÙØ�)˜a�C•.Ô Ø!ˆ	�A•#‰ÜÐä
ˆa‹&€CÜ
ˆa‹&€Cä�C˜˜aÓ €Eà€Hä�1�Q•3ŽZˆØ”GœC¤ a¨£Ó,¬c´%¸¸1³+Ó.>ÀÓBÕBŠñ ð �|‰|‹~€HäˆEÕ˜eÕ.Ø�q•S�M˜I¨¥c�NÕ*¨XÕ5ó	7Ø9:õ	;€Að 	ˆ1„uÙà	€AØ	€AØ€JØ€EÜ”%˜“(‹^€Fç
ˆ&Ü�MŠM˜& !Ó$ QÕ'ˆØ�‰�aÔà× Ñ   AÓ&¨×*Ô*Ùà—‘  1Ó%¨Õ)ˆà�Z‰Z˜˜!�˜QÓ×,Ñ,¨QÓ/ˆØ�Z‰Z˜˜!�˜QÓ×,Ñ,¨QÓ/ˆô $ B¨¨A¸ÓCˆàŠ:Ø��FˆAØ�1ŒuÙÙà�<�<ˆ<Ø—‘˜tÓ$×1Ñ1°!Ó4ˆAØˆHà�]‰]˜6Ó"×/Ñ/°Ó2ˆà×Ñ˜!ÔØ�‰�RÔØ	ˆQ�ˆà��6Ü)¨*°e¸TÀQÅ3ÈÓJˆAä˜1Ó  Õ# e§n¡n°TÓ&:Õ:ˆAØ—H‘H˜Q˜q�S“MˆEà�x !¥•}Ô$ÙØ�x !¥•}Ô$Ø %�˜1�‘Ü&Ð&àˆHár   c           	     ó&  € V P                   VP                   8X  d'   V P                   P                  P                  '       g   Q h\        W4      pVe   V# V P                   pVP                  pV P                  4       w  rPVP                  4       w  raVP                  P                  WV4      pVP                  P                  V P                  VP                  4      pVP                  P                  p	\        V4       FK  p
W“P                  P                  \        W
4      P                  \        W4      P                  4      ,          p	KM  	  \        V P                  4       VP                  4       4       UUu. uF  w  r¼\        W¼4      NK  	  ppp\        V4      p^p^p \        V4      pV	V,          ^ 8X  d   \        V4      pK  V P!                  V4      pVP!                  V4      p \#        VVVWÞ4      pTf   K^  TP'                  T4      P!                  T4      pT^8X  d   TpTpK‹  \)        TXTT4      pTT,          pTT8X  g   TpK­  TP                  4       ^,          pT P+                  T4      w  ppTP+                  T4      w  ppT'       d   Kö  T'       d   EK  TP                  ^ 8  d   T) pTP'                  T4      pTP'                  YW,          4      pTP'                  Yg,          4      pTTT3# u uppi   \$         d    ^p EKp  i ; i)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

)r   r   r>   r   rW   r?   r*   r   r   r3   rq   r’   Údegreesrt   r¬   r   r   r°   r   r   rŽ   rB   )r   r   rC   r   r_   rD   rE   rF   r+   rw   r;   ÚfdegÚgdegr²   r³   rH   r"   r    r!   r,   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   s   &&                           r   Úmodgcd_multivariaterÇ   '  s}  € ð\ �6‰6�Q—V‘VÔ §¡§¡× 3× 3Ð 3Ð3Ð3ä˜!Ó€FØÒØˆà�6‰6€DØ�
‰
€Að �K‰K‹M�E€BØ�K‰K‹M�E€BØ	�‰�‰˜Ó	 €Bà�K‰K�O‰O˜AŸD™D !§$¡$Ó'€Eà—‘—‘€IÜ�1ŽXˆØ—[‘[—_‘_¤U¨1£[§^¡^´U¸1³[·^±^ÓDÕDŠ	ñ ô 36°a·i±i³kÀ1Ç9Á9Ã;Ô2OÔPÑ2O¡J D”�D–Ñ2O€HÑPÜ�X“€Ià	€AØ	€Aà
Ü�a‹LˆØ˜!�m˜qÔ Ü˜!“ŠAà�^‰^˜AÓˆØ�^‰^˜AÓˆð	ä'¨¨B°°8ÓGˆBð
 Š:Ùà�]‰]˜5Ó!×.Ñ.¨qÓ1ˆØ�Œ6ØˆAØˆFÙä;¸BÀÈÈ1ÓMˆØ	ˆQ�ˆà�VŒ|ØˆFÙà�L‰L‹N˜1ÕˆØ—U‘U˜1“X‰
ˆˆdØ—U‘U˜1“X‰
ˆˆdß‰tŸDšDØ�t‰t�aŒxØ�S�Ø—‘˜RÓ ˆAØ—/‘/ "¥(Ó+ˆCØ—/‘/ "¥(Ó+ˆCØ�c˜3�;Ðùó] Qøô"  ô 	ØˆAÛð	ús   Å7K8Ç)K> Ë>LÌLc                óÈ   € V P                   p\        V P                  4       VP                  4       W#P                  4      w  rEVP	                  V4      VP	                  V4      3# )zS
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Ì   º  sK   € ð
 �6‰6€DÜ §
¡
£¨a¯j©j«l¸A¿{¹{ÓKÑ€HØ�?‰?˜8Ó$ d§o¡o°hÓ&?Ð?Ð?r   c                óä  € V P                   pVP                  pVP                  4       pV^,          pWV,
          ^,
          pY#P                  r˜YP                  rºV
P                  4       V8”  dR   \        WŠV4      ^ ,          pY¨WÊ,          ,
          P                  V4      r¨Y¹WË,          ,
          P                  V4      r¹Kf  Y«ríVP                  4       V8”  g   \        WâV4      ^8w  d   R# VP                  pV^8w  dR   VP                  Wñ4      pVP                  V4      P                  V4      pVP                  V4      P                  V4      pVP                  4       pV! V4      V! V4      ,          # )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]_

N)r   r   r   r   r   rÌ   r   r(   r   r   r   Úto_field)Úcr"   rH   r   r   ÚMr¥   ÚDÚr0Ús0Úr1Ús1r]   r}   r˜   Úlcr&   Úfields   &&&               r   Ú!_rational_function_reconstructionrØ   Ä  s#  € ðJ �6‰6€DØ�[‰[€FØ	�‰‹
€AØ	ˆQ�€AØ	���	€Aà—	‘	ˆØ—‘ˆà
�)‰)‹+˜Œ/Ü�b˜aÓ  Õ#ˆØ˜3�6•k×/Ñ/°Ó2ˆBØ˜3�6•k×/Ñ/°Ó2ŠBà€qØ‡x�xƒz�A„~œ  qÓ)¨QÔ.Ùà	
�‰€BØ	ˆQ„wØ—‘˜bÓ$ˆØ�L‰L˜Ó×,Ñ,¨QÓ/ˆØ�L‰L˜Ó×,Ñ,¨QÓ/ˆà�M‰M‹O€Eá�‹8‘e˜A“hÕÐr   c                óJ  € VP                   pV P                  4        F‚  w  rgV^ 8X  d   \        WqV4      pV'       g    R# MZVP                  P                   pVP	                  V4      P                  4        F!  w  rš\        W¡V4      pV'       g     R# W¸V	&   K#  	  W…V&   K„  	  V# )au  
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

N)r   rX   rØ   r   Údrop_to_ground)rJ   r"   rH   r   r_   rK   ra   r4   ÚcoeffhÚmonrÏ   rF   s   &&&&&       r   Ú$_rational_reconstruction_func_coeffsrÝ     s˜   € ð\ 	�	‰	€AàŸ™ž‰ˆØ�Œ6Ü6°uÀÓCˆFçÚð ð —[‘[×%Ñ%ˆFØ×.Ñ.¨qÓ1×;Ñ;Ö=‘�Ü6°q¸QÓ?�çÛà �s“ñ >ð ˆ%‹ñ# 'ð& €Hr   c                óê   € V P                   p\        V P                  4       VP                  4       W#P                  4      w  rEpVP	                  V4      VP	                  V4      VP	                  V4      3# )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ÚtrK   s   &&&    r   Ú	_gf_gcdexrá   L  sW   € ð �6‰6€DÜ�q—z‘z“| Q§Z¡Z£\°1·k±kÓB�G€Aˆ!Ø�?‰?˜1Ó˜tŸ™¨qÓ1°4·?±?À1Ó3EÐEÐEr   c                ó¾   € V P                   pVP                  V4      pVP                  V4      pV P                  V4      P	                  W.4      P                  V4      # )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  sR   € ð0 �6‰6€DØ×Ñ˜tÓ$€GØ	�‰˜Ó	€Bà�>‰>˜!Ó× Ñ  ' Ó/×<Ñ<¸QÓ?Ð?r   c                óB  € V P                   p\        WV4      p \        WV4      pV'       d²   T pVP                  ^ 4      p\        VP	                  V4      W#4      w  rxp	V	^8X  g   R#  VP                  ^ 4      p
W¦8  d   MXWtP	                  V4      ,          P                  V4      p\        WQP                  W¦,
          ^ 34      V,          ,
          W#4      pKq  Tp TpK¹  \        VP	                  V 4      W#4      ^ ,          P                  V4      p\        W,          W#4      # )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]`

N)r   ræ   r   rá   Údmp_LCr^   r   )r   r   rä   r"   r   r$   r%   r&   Ú_r*   r'   r]   Úlcfinvs   &&&&         r   Ú_euclidean_algorithmrë   y  sñ   € ð8 �6‰6€Däˆq˜1Ó€AÜˆq˜1Ó€Aç
ØˆØ�h‰h�q‹kˆÜ! $§+¡+¨a£.°'Ó=‰ˆ�#à�aŒxÙàØ—Z‘Z “]ˆFØŒ|ØØŸ;™; sÓ+Õ+×5Ñ5°dÓ;ˆCÜ˜Ÿ{™{¨F­L¸!Ð+<Ó=¸cÕAÕAÀ7ÓNŠCàˆØŠä�t—{‘{ 1“~ wÓ2°1Õ5×>Ñ>¸tÓD€Fä�!•*˜gÓ)Ð)r   c                ó¸  € V P                   pVP                  VP                  ^,          VP                  ^ ,          3R7      pVP                  V4      pT pVP	                  4       pVP	                  4       pVP	                  ^4      p	\        V4      P                  V4      p
VP                  pV'       Ed%   Wx8¼  Ed   \        V4      P                  V4      pWj,          VP                  Wx,
          ^ 34      V,          ,
          pV'       d   VP                  V4      pVP	                  ^4      pV'       d’   Wy8¼  dŒ   \        VP                  V4      4      P                  V4      pVP                  V4      VP                  ^ Wy,
          34      V,          ,
          pV'       d   VP                  V4      pVP	                  ^4      pK™  VP	                  4       pEK-  V# )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]_

rT   )
r   r[   rU   r^   r   rm   r   r   r   r   )r   rK   rä   r"   r   Úzxringr$   r'   r´   ÚdegmÚlchÚlcmÚlcrems   &&&&         r   Ú_trial_divisionrò   ±  sd  € ðB �6‰6€Dà�Z‰Z §¡¨a¥°$·,±,¸qµ/Ð BˆZÓC€Fà×Ñ˜tÓ$€Gà
€Cà�Z‰Z‹\€FØ�8‰8‹:€DØ�>‰>˜!Ó€Dä
ˆa‹&�/‰/˜$Ó
€CØ
�*‰*€Cç
ˆ#�&•.ä�C“×!Ñ! $Ó'ˆØ�g˜Ÿ™ V¥]°AÐ$6Ó7¸Õ=Õ=ˆßØ×"Ñ" 1Ó%ˆCØ—‘˜A“ˆç�f”nä˜Ÿ™ VÓ,Ó-×6Ñ6°tÓ<ˆEØ—.‘. Ó%¨×(9Ñ(9¸1¸f½mÐ:LÓ(MÈeÕ(SÕSˆCßØ×&Ñ& qÓ)�Ø—Z‘Z “]ŠFà—‘“‹à€Jr   c                ó  € V P                   P                  V P                   P                  P                   P                  V4      R7      pVP                  pV P                  4        F  w  rVVP                  W4      WE&   K  	  V# )zO
Evaluate a polynomial `f` at `a` in the `i`-th variable of the ground
domain.
©r   )r   r[   r   Údropr   rX   rs   )r   r;   r}   r   r¿   ra   r4   s   &&&    r   Ú_evaluate_groundrö   ö  sc   € ð
 �6‰6�<‰<˜qŸv™vŸ}™}×1Ñ1×6Ñ6°qÓ9ˆ<Ó:€DØ	�‰€BàŸ™ž‰ˆØ—N‘N 1Ó(ˆ‹	ñ &ð €Ir   c           
     ó@  € V P                   pVP                  p\        V\        4      '       d   VP                  pM\        WW#4      # V^8X  d   VP                   P                  4       pMVVP                   P                  V^,
          4      pVP                  VP                  P                   P                  4       R7      pVP                  VR7      p^p	^p
VP                  V 4      VP                  V4      ,          pVP                  p. p. p. p\        \        V4      4      pV'       Edó   \        P                  ! V^4      ^ ,          pVP                  V4       V^8X  d%   VP!                  V^,
          V4      V,          ^ 8H  pM+VP!                  V^,
          V4      P#                  V4      ^ 8H  pV'       d   K˜  \%        W¶^,
          V4      p\%        W&^,
          V4      pVP'                  VVP                  V4      .4      ^ 8X  d   Kç  \%        W^,
          V4      p\%        W^,
          V4      p\)        VVVV4      pVf   V
^,          p
W©8”  d   R# EK3  V^8X  d   V# VP+                  4       .^ .V^,
          ,          ,           pV^8”  dd   VP-                  4        FO  w  ppV^ ,          V^ ,          8X  g   K  VP.                  \1        VR,          4      8”  g   K@  VP.                  VR&   KQ  	  V.pV.pV^8X  d&   VP                  P3                  4       P4                  pM.VP                  P                  P3                  4       P4                  pVP                   P6                  ^ ,          p\9        WÞV4       FB  w  pp p!V!V8X  g   K  VP;                  V4       VP;                  V 4       VVV,
          ,          pKD  	  VP#                  V4      pVP;                  V4       VP;                  V4       VP;                  V4       V	^,          p	\=        VVWF^,
          VRR7      p"\?        V"VVW†^,
          4      p"V"f   EK  V^8X  dœ   VP                  P@                  p#V#P                   P4                  p$V"PC                  4        FZ  pV#P                   PE                  \G        V$PI                  4       VPJ                  PI                  4       VV#P                  4      4      p$K\  	  M»VP                  P                  P@                  p#V#P                   P4                  p$V"PC                  4        Fq  pVPC                  4        FZ  p%V#P                   PE                  \G        V$PI                  4       V%PJ                  PI                  4       VV#P                  4      4      p$K\  	  Ks  	  VPM                  V$P#                  V4      4      p$V! V"PO                  V$4      PQ                  4       4      P#                  V4      p"\S        V V"W#4      '       d   EKã  \S        VV"W#4      '       d   EKù  V"# R# )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ô   Nºé   NNT)r•   )*r   r   r�   r   rW   rë   rÎ   rÚ   r[   rè   r   r¬   r3   r­   r®   r¯   rs   r   rö   r$   Ú_func_field_modgcd_pr   rX   ÚLMÚtupleÚget_ringr   r2   r’   r›   r™   rÝ   r×   Ú
itercoeffsr\   r   rÉ   r—   Ú
domain_newr   Úas_exprrò   )&r   r   rä   r"   r   r   r_   ÚqdomainÚqringr8   r¼   r+   r|   r“   r½   ÚLMlistr¾   r}   ÚtestÚgammaaÚminpolyar¿   rÀ   rÁ   rû   ra   r4   Úevalpoints_aÚheval_arH   rà   r˜   ÚhbÚLMhbrK   r#   ÚdenrÏ   s&   &&&&                                  r   rú   rú     sÏ  € ðT �6‰6€DØ�[‰[€Fä�&œ.×)Ò)Ø�L‰L‰ä# A¨'Ó5Ð5àˆA„vØ—+‘+×&Ñ&Ó(‰à—+‘+×,Ñ,¨Q°­UÓ3ˆØ—-‘- w§~¡~×':Ñ':×'CÑ'CÓ'E�-ÓFˆà�J‰J˜gˆJÓ&€Eà	€AØ	€Að �K‰K˜‹N˜TŸ[™[¨›^Õ+€Eà�J‰J€Eà€JØ€EØ€FÜ”%˜“(‹^€Fç
ˆ&Ü�MŠM˜& !Ó$ QÕ'ˆØ�‰�aÔà�Œ6Ø—>‘> ! A¥# qÓ)¨AÕ-°Ñ2‰Dà—>‘> ! A¥# qÓ)×6Ñ6°qÓ9¸QÑ>ˆDçÙä! %¨1­¨aÓ0ˆÜ# G¨q­S°!Ó4ˆà�:‰:�x §¡¨Q£Ð0Ó1°QÔ6Ùä˜a 1¥ aÓ(ˆÜ˜a 1¥ aÓ(ˆô " " b¨(°AÓ6ˆàŠ:Ø��FˆAØŒuÙÚà�Œ7ØˆIà�i‰i‹kˆ]˜a˜S ! A¥#�YÕ&ˆØˆqŒ5Ø "§¡¦‘��uØ˜•8˜r !�uÖ$¨¯©´E¸"¸R½&³MÖ)AØ"ŸX™X�B�r“Fñ !/ð �sˆØ�$ˆØ�Œ6Ø—‘×%Ñ%Ó'×+Ñ+‰Aà—‘×#Ñ#×,Ñ,Ó.×2Ñ2ˆAà�F‰F�K‰K˜�Nˆä˜z°&Ö9‰KˆAˆr�4Ø�rŽzØ×#Ñ# AÔ&Ø—‘˜rÔ"Ø�a˜!•e•’ñ	 :ð �N‰N˜1ÓˆØ×Ñ˜!ÔØ�‰�RÔØ�‰�bÔØ	ˆQ�ˆô & l°G¸TÀQÅ3ÈÐRVÔWˆô 1°°A°q¸%À1ÅÓEˆàŠ9Úà�Œ6Ø—,‘,×$Ñ$ˆCØ—(‘(—,‘,ˆCàŸ™ž�Ø—h‘h×)Ñ)¬&°·±³ÀÇÁ×AUÑAUÓAWØ˜3Ÿ:™:ó+'ó (’ò (ð
 —,‘,×%Ñ%×+Ñ+ˆCØ—(‘(—,‘,ˆCàŸ™ž�Ø×)Ñ)Ö+�AØŸ(™(×-Ñ-¬f°S·\±\³^ÀQÇWÁW×EUÑEUÓEWØ˜sŸz™zó/+ó ,’Có ,ñ (ð
 ×Ñ˜s×/Ñ/°Ó2Ó3ˆÙ�—‘˜cÓ"×*Ñ*Ó,Ó-×:Ñ:¸1Ó=ˆä˜q ! W×0Õ0¼ÈÈAÈw×9ZÕ9ZØˆHár   c                ó–  € V ^ 8  d	   W,          p YP                   rCYP                  re\        V^,          4      p\        V4      V8¼  d)   W5,          pYSW…,          ,
          rSYdW†,          ,
          rdK8  \	        \        V4      4      V8¼  d   R# V^ 8  d   V) V) r©MV^ 8”  d   YVr©MR# VP                  4       pV! V	4      V! V
4      ,          # )ap  
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]_

N)r   r   r   ÚintÚabsÚ	get_field)rÏ   rH   r   rÒ   rÓ   rÔ   rÕ   rG   r]   r}   r˜   r×   s   &&&         r   Ú _integer_rational_reconstructionr  ª  s°   € ðH 	ˆ1„uØ	�ˆà—‘ˆØ—
‘
ˆä��Q•‹K€Eä
ˆb‹'�UÔ
Ø�hˆØ˜#�&•[ˆBØ˜#�&•[ŠBä
Œ3ˆr‹7ƒ|�uÔÙà	ˆA„vØˆs�R�C‰1Ø	ˆaŒØ‰1áà×ÑÓ€Eá�‹8‘e˜A“hÕÐr   c                ó2  € VP                   p\        VP                  \        4      '       d   \        pVP                  P
                  pM\        pV P
                  P                  pV P                  4        F  w  rgV! WqV4      pV'       g    R# WƒV&   K  	  V# )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  rX   )	rJ   rH   r   rK   Úreconstructionr   ra   r4   rÛ   s	   &&&      r   r  r  ê  sw   € ðR 	�	‰	€Aä�$—+‘+œ~×.Ò.Ü<ˆØ—‘×!Ñ!‰ä9ˆØ—‘—‘ˆàŸ™ž‰ˆÙ ¨&Ó1ˆçÚàˆ%‹ñ 'ð €Hr   c                ó”  € V P                   pVP                  p\        V\        4      '       dT   VP                  pVP                   P                  VP                  P                  4       R7      pVP                  VR7      pM,^ pVP                  VP                  P                  4       R7      pV P                  4       w  r€VP                  4       w  r‘VP                  V 4      VP                  V4      ,          p
VP                  p^p. p. p. p \        V4      pV
P                  V4      ^ 8X  d   K$  V^ 8X  d   W¼,          ^ 8H  pMVP                  V4      ^ 8H  pV'       d   KU  V P                  V4      pVP                  V4      pVP                  V4      p\        VVVV4      pVf   Kœ  V^8X  d   VP                  # VP                  4       .^ .V,          ,           pV^ 8”  dd   VP                  4        FO  w  ppV^ ,          V^ ,          8X  g   K  VP                   \#        VR,          4      8”  g   K@  VP                   VR&   KQ  	  TpTp\%        WÞV4       F'  w  pppVV8X  g   K  \'        VVVV4      pVV,          pK)  	  VP)                  V4       VP)                  V4       VP)                  V4       \+        VVV4      pVf   EK»  V^ 8X  d   VP-                  4       ^,          pMoVP                  P                  pVP/                  4        F4  pVP                  P1                  VVP-                  4       ^ ,          4      pK6  	  VP3                  V4      pVP5                  V4      pVP                  4       ^,          p\7        V P3                  V4      VV4      '       d   EK–  \7        VP3                  V	4      VV4      '       d   EK»  V# )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   r   r�   r   rW   r[   r  r?   rè   r   r   r   rú   r   r   rX   rû   rü   r’   rŽ   r›   r  Úclear_denomsrþ   rð   r   r^   rò   )r   r   rä   r   r   r_   ÚQQdomainÚQQringrD   rE   r+   r|   r"   ÚprimesÚhplistr  r  r    r!   Úminpolypr,   rû   ra   r4   rJ   rH   r7   r6   ÚLMhqrK   r  s   &&&                            r   Ú_func_field_modgcd_mr  '  s  € ðD �6‰6€DØ�[‰[€Fä�&œ.×)Ò)Ø�L‰LˆØ—;‘;×$Ñ$¨F¯M©M×,CÑ,CÓ,EÐ$ÓFˆØ—‘ 8�Ó,‰àˆØ—‘ 4§;¡;×#8Ñ#8Ó#:�Ó;ˆà�K‰K‹M�E€BØ�K‰K‹M�E€Bð �K‰K˜‹N˜TŸ[™[¨›^Õ+€Eà�J‰J€Eà	€AØ€FØ€FØ€Fà
Ü�a‹Lˆà×Ñ˜aÓ  AÔ%Ùà�Œ6Ø•I ‘N‰Dà×&Ñ& qÓ)¨QÑ.ˆDçÙà�^‰^˜AÓˆØ�^‰^˜AÓˆØ×'Ñ'¨Ó*ˆä! " b¨(°AÓ6ˆàŠ:Ùà�Œ7Ø—8‘8ˆOà�i‰i‹kˆ]˜a˜S �UÕ"ˆØˆqŒ5Ø "§¡¦‘��uØ˜•8˜r !�uÖ$¨¯©´E¸"¸R½&³MÖ)AØ"ŸX™X�B�r“Fñ !/ð ˆØˆä˜v¨vÖ6‰KˆAˆr�4Ø�rŽzÜCÀBÈÈAÈqÓQ�Ø�Q•’ñ 7ð
 	�‰�aÔØ�‰�bÔØ�‰�bÔä0°°Q¸Ó?ˆàŠ:Úà�Œ6Ø—‘Ó! !Õ$‰Aà—-‘-×#Ñ#ˆCØŸ™ž�Ø—m‘m×'Ñ'¨¨U×-?Ñ-?Ó-AÀ!Õ-DÓE’ñ )à—‘˜cÓ"ˆAð �J‰J�tÓˆØ�K‰K‹M˜!Õˆä §¡¨RÓ 0°!°W×=Õ=Ü˜AŸL™L¨Ó,¨a°×9Õ9ØˆHr   c                ó¾  € VP                   p\        VP                  \        4      '       d   VP                  P                  pMVP                  pVP                  pV P                  4        F?  pVP                  4        F(  pV'       g   K  VP                  WFP                  4      pK*  	  KA  	  V P                  4        EF  w  ruVP                  4       pVP                  P                  p\        VP                  \        4      '       d   VP                  VR,          4      p\        V4      p	\        V	4       F›  p
WZ,          '       g   K  VP                  WZ,          V,          4      V,          pV^ ,          Wš,
          ^,
          3V9  d   WbV^ ,          Wš,
          ^,
          3&   Kq  W'^ ,          Wš,
          ^,
          3;;,          V,          uu&   K�  	  EK  	  V# )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ø   )r   r�   r   r   r   rþ   Úto_listrð   ÚdenominatorrX   r   Úlenr3   Úconvert)r   r   Úf_r   r  r4   rÏ   ra   rH   r8   r;   s   &&         r   Ú_to_ZZ_polyr#  Ã  sN  € ð2 
�‰€Bä�$—+‘+œ~×.Ò.Ø—‘×#Ñ#‰à—‘ˆà
�*‰*€Cà—‘–ˆØ—‘–ˆAß‰qØ—j‘j §m¡mÓ4’ó !ñ  ð
 Ÿ™Ÿ‰ˆØ—‘“ˆØ�K‰K�O‰OˆÜ�d—k‘k¤>×2Ò2Ø—‘˜E "�IÓ&ˆAÜ�‹Jˆä�q–ˆAØ�xŽxØ—N‘N 5¥8¨c¥>Ó2°QÕ6�à˜!•H˜a�c !�eÐ$¨BÔ.Ø,-˜˜a� !¥# a¥%Ð(Ó)à˜a� !¥# a¥%Ð(×)¨QÕ.Õ)ô ñ &ð  €Ir   c                ó’  € VP                   pVP                  p\        V P                  P                   \        4      '       d”   V P                  4        F}  w  rEVP                  4        Fd  w  rgV^ ,          3V,           pV! VP                  V4      .^ .V^,          ,          ,           4      p	Wƒ9  d   W“V&   KP  W8;;,          V	,          uu&   Kf  	  K  	  V# V P                  4        F]  w  rEV^ ,          3pV! VP                  V4      .^ .V^,          ,          ,           4      p	Wƒ9  d   W“V&   KI  W8;;,          V	,          uu&   K_  	  V# )a.  
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   rX   )
r   r   r   r"  ra   r4   rÜ   ÚcoefrH   rÏ   s
   &&        r   Ú_to_ANP_polyr&  ý  s  € ð0 �[‰[€FØ	�‰€Bä�!—&‘&—-‘-¤×0Ò0ØŸK™KžM‰LˆEØ"Ÿ_™_Ö.‘	�Ø˜1•X�K #Õ%�Ù˜FŸM™M¨$Ó/Ð0°A°3°u¸Qµxµ<Õ?Ó@�à”;Ø�q“Eà—E˜Q•J•Eó /ñ *ð( €Ið ŸK™KžM‰LˆEØ�q•�ˆAÙ˜Ÿ™ eÓ,Ð-°°°E¸!µHµÕ<Ó=ˆAàŒ{Ø�1“à—˜•
•ñ *ð €Ir   c                óv   € VP                   pV P                  4        F  w  r4VP                  V4      W#&   K  	  V# )zc
Change representation of the minimal polynomial from ``DMP`` to
``PolyElement`` for a given ring.
)r   Útermsr   )rä   r   Úminpoly_ra   r4   s   &&   r   Ú_minpoly_from_denser*  0  s6   € ð
 �y‰y€HàŸ™ž‰ˆØŸ+™+ eÓ,ˆ‹ñ (ð €Or   c                ó�  € V P                   pVP                  ! \        ^VP                  4      !  pVP                  P                   pV! V P                  4       4      pVP                  pVP                  4        F*  p\        WV4      ^ ,          pWSP                  8X  g   K'  WP3u # 	  WPP                  VP                  V4      4      3# )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Ú   r3   rW   r   r   r   rþ   Úfunc_field_modgcdr   r]   r^   )r   Úfringr   r#   r"  rb   r4   s   &      r   Ú_primitive_in_x0r.  =  sœ   € ð �F‰F€EØ×Ò¤ q¨%¯+©+Ó!6Ñ7€DØ
�+‰+×
Ñ
€CÙ	ˆa�i‰i‹kÓ	€BØ�8‰8€Dà—‘–ˆÜ  Ó-¨aÕ0ˆØ—7‘7Ž?Ø�7ŠNñ !ð
 —‘�t—}‘} UÓ+Ó,Ð,Ð,r   c                ón  € V P                   pVP                  pVP                  pW!P                   8X  d   VP                  '       g   Q h\	        W4      pVe   V# \        R4      pVP                  VP                  V3,           VP                  P                  4       R7      pV^8X  dg   \        W4      p\        W4      p	VP                  ^ 4      P                  VP                  P                  4       4      p
\        W‰V
4      p\        W²4      pMë\!        V 4      w  rÀ\!        V4      w  rÑ\#        WÍ4      ^ ,          pVP$                  ! \'        ^V4      !  p\        W4      p\        W4      p	\)        VP                  VP                  ^ 4      4      p
\        W‰V
4      p\        W²4      p\!        V4      w  ppW¾P+                  V4      ,          pWP+                  V4      ,          p WP+                  V4      ,          pVP-                  VP.                  4      pW°P1                  V4      VP1                  V4      3# )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]_

Úz)rU   r   )r   r   rW   Úis_Algebraicr   r   r[   rU   rý   r#  rõ   r\   Úmodr  r  r&  r.  r,  rÚ   r3   r*  r^   r@   r   r]   )r   r   r   r   r8   rC   r0  ÚZZringr"  Úg_rä   rK   Úcontx0fÚcontx0gÚcontx0hÚZZring_Úcontx0h_s   &&               r   r,  r,  R  sÍ  € ðP �6‰6€DØ�[‰[€FØ�
‰
€Aà—6‘6Œ>˜f×1×1Ð1Ð1Ð1ä˜!Ó€FØÒØˆäˆc‹
€Aà�Z‰Z §¡°¨tÕ 3¸F¿M¹M×<RÑ<RÓ<TˆZÓU€FàˆA„vÜ˜Ó#ˆÜ˜Ó#ˆØ—+‘+˜a“.×+Ñ+¨F¯J©J×,>Ñ,>Ó,@ÓAˆä  ¨Ó1ˆÜ˜Ó!‰ô & aÓ(‰
ˆÜ% aÓ(‰
ˆÜ# GÓ5°aÕ8ˆà×'Ò'¬¨q°!«Ñ5ˆä˜Ó$ˆÜ˜Ó$ˆÜ% f§j¡j°'·,±,¸q³/ÓBˆä  ¨Ó1ˆÜ˜Ó!ˆä& qÓ)‰ˆ�!Ø	×Ñ˜dÓ#Õ#ˆØ	×Ñ˜dÓ#Õ#ˆØ	×Ñ˜dÓ#Õ#ˆà	�‰�Q—T‘TÓ€Aà�e‰e�A‹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<   rR   re   ri   rm   rq   r‚   rŽ   r™   rª   r°   rÇ   rÌ   rØ   rÝ   rá   ræ   rë   rò   rö   rú   r  r  r  r#  r&  r*  r.  r,  © r   r   Ú<module>rB     sè   ðÝ #Ý #Ý %Ý .÷4õ 4å 3å Û òò,?ò.òB>òB~òB:.òz-ò`2òj	òH5òV`ôF>òBQòhVòrPòf@ò?òDCòLFò@ò>5*ôpBòJòcòL=ò@:òzYòx7òt0òf
ò-ô*T!r   