K ii4ddlmZddlmZddlmZddlmZddlm Z m Z m Z m Z m Z ddlmZddlmZddlZd Zd Zd Zd Zd ZdZdZdZdZdZdZd)dZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'd*dZ(dZ)d Z*d!Z+d"Z,d#Z-d$Z.d%Z/d&Z0d'Z1d(Z2y)+)Dummy) nextprimecrt)PolynomialRing)gf_gcd gf_from_dictgf_gcdexgf_divgf_lcm)ModularGCDFailed)sqrtNc|j}|s%|s#|j|j|jfS|sW|j|jjkr| |j|j fS||j|jfS|sW|j|jjkr| |j |jfS||j|jfSy)zn Compute the GCD of two polynomials in trivial cases, i.e. when one or both polynomials are zero. N)ringzeroLCdomainone)fgrs \/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/polys/modulargcd.py _trivial_gcdr s 66D yy$))TYY..  44$++"" "2tyy488)+ +dii) )  44$++"" "2y$))+ +dhh ) ) c|jj}|r|}|j}|j|j|} |j}||krnD||j ||z fj ||jzz j|}Z|}|}|r|j |j|j|j|S)zM Compute the GCD of two univariate polynomials in `\mathbb{Z}_p[x]`. )rrdegreeinvertr mul_monom mul_ground trunc_ground)fpgppdomremdeglcinvdegrems r_gf_gcdr(#s ''..C iik 255!$ZZ\F|v|o6AA%#&&.QQ__`abC     ==BEE1- . ; ;A >>rcJ|jjj|j|j}d}t |}||zdk(rt |}||zdk(r|j |}|j |}t |||}|j}|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)rrgcdrrrr(r)rrgammar"r r!hpdeghps r_degree_bound_univariater/:s& FFMM  addADD )E A! A !)q. aL !)q.  B  B R B IIKE Lrc D|j}|jjd}|jj}t |dzD]?}t ||g|j ||z|j ||zgdd||f<A|j|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 rr*T symmetric)rrgensrrangercoeff strip_zero)r-hqr"qnxhpqis r,_chinese_remainder_reconstruction_univariater=[sl A  QA '',,C 1Q3ZUA!Q$!Q$ @DQRSTQD UNN Jrc|j|jk(r |jjjsJt||}||S|j}|j \}}|j \}}|jj ||}t ||}|dk(r/|||j||z|j||zfS|jj |j|j}d} d} t| } || zdk(rt| } || zdk(r|j| } |j| } t| | | } | j}||kDrm||krd} |}w| j|j| } | dk(r| } | }t| | | }| | z} ||k(s|}|j|j}|j!|\}}|j!|\}}|sR|sP|jdkr| }|j|}|j||z}|j||z}|||fSX)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]_ rr*)rris_ZZr primitiver+r/rrrrr(rr= quo_groundcontentdiv)rrresultrcfcgchboundr,mr"r r!r-r.hlastmhmhfquofremgquogremcffcfgs rmodgcd_univariaterSsIF 66QVV  3 33 3 !Q F  66D KKMEB KKMEB R B $Q *E zBxbBh/bBh1GGG KKOOADD!$$ 'E A A  aLai1n! Aai1n^^A  ^^A  RQ   5=  U]AE  ]]5 ! . .q 1 6AF  9"fa K QV|F  MM"**, 'UU1X dUU1X dDttaxS R A//"(+C//"(+Cc3; O rc |j}|j}|j}i}|jD]"\}}|dd|vri||dd<|||dd|d<$g}t |j D]}t |t|||||}|j|j|dz } | j|j|} | |j| j|fS)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) Nr*symbols)rrngens itertermsitervaluesrr clonerW from_denserquoset_ring) rr"rr#kcoeffsmonomr5contyringcontfs r _primitiverfsR 66D ++C A F . u ":V #!#F5": (-uSbz59%. Dfmmo&AdL37C@A JJt||AaC0J 1E   T " / / 2E !%%t,- --rc|jj}d|dz z}|jD]}|dd|kDs |dd}|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) )rr*NrU)rrX itermonoms)rr`degfrbs r_degrjZsTP  A 1Q3>> 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*rVrNrU)rrXr\rWr3rjrrY) rrr`rdyrilcfrbr5s r_LCrnsP 66D A JJt||AaC0J 1E 1 A 7D **C & u ":  5E"I% %C& Jrc|j}|j}|jD]\}}||f|d|z||dzdz}|||<!|S)zS Make the variable `x_i` the leading one in a multivariate polynomial `f`. Nr*)rrrY)rr<rfswaprbr5 monomswaps r_swaprrse 66D IIE ! u1XK%)+eAaCDk9  i! Lrc|j}|jj|j|j}|jjt |djt |dj}||z}d}t |}||zdk(rt |}||zdk(r|j |}|j |}t||\} }t||\} }t| | |} | j} tt|t||} t|D]|}| jd||zs|jd|j |}|jd|j |}t|||}|j}|| fcSt|j|j| fS)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)rrr+rrrrrrfr(rrnr4evaluatemin)rrrgamma1gamma2 badprimesr"r r!contfpcontgpconthp ycontbounddeltaafpagpahpaxbounds r_degree_bound_bivariatersT 66D [[__QTT144 (F [[__U1a[^^U1a[^^ >> 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:t||g||gddS)NTr1rr)cpcqr"r8rs rcrt_z<_chinese_remainder_reconstruction_multivariate..crt_ls$#q!fr2h$?BC Cr) setmonoms intersectiondifference_updaterrr isinstancer._chinese_remainder_reconstruction_multivariate) r-r7r"r8hpmonomshqmonomsrrr;rrbrs @rrrsP299;H299;H  " "8 ,F v& v& WW^^F ;;D '',,C"''...1= D6"U)RY15E 61"U)T1a0E 11$5 1a0E 1 Jrc|j}|r0|jj}|jj|}n|j}|j|}t||D]t\} } |j} |j} |D]} | | k(r | || z z} | | | z z} |j | |} | j | }|| j||zz }v|j|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}]` ) rrr3ziprrrr_r) evalpointshpevalrr<r"groundr-rrlr~rnumerdenombr5s r_interpolate_multivariaterysN B ## KK  Q  IIaLj&) )3  AAv QUNE QUNE   eQ'  ' cll4 5(( ) ??1 rc |j|jk(r |jjjsJt||}||S|j}|j \}}|j \}}|jj ||}t ||\}}||cxk(rdk(r2nn/|||j||z|j||zfSt|d} t|d} | j} | j} t | | \} }| |cxk(rdk(r2nn/|||j||z|j||zfS|jj |j|j}|jj | j| j}||z}d}d} t|}||zdk(rt|}||zdk(r|j|}|j|}t||\}}t||\}}t|||}|j}||kDr||krd}|}tt|t||}|j}|j}|j}t!| |z | |z | |z |zdz}||krd}g} g}!d}"t#|D]}#|j%d|#}$|$|zs|j%d|#j|}%|j%d|#j|}&t|%|&|}'|'j}(|(|kDr|(|krd}|(}d}"nP|'j|$j|}'| j'|#|!j'|'|dz }||k(sn|"r||krt)| |!|d|})t|)|d})|)|j+|z})|)jd}*|*| kDrL|*| krd}|*} W|)j|j|})|dk(r|}|)}+t-|)+||},||z}|,|+k(s|,}+|,j/|,j1}-|j3|-\}.}/|j3|-\}0}1|/sR|1sP|-jdkr| }|-j|}-|.j||z}2|0j||z}3|-|2|3fS:)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]_ rr*TF)rrr?rr@r+rrrrrrrrrfr(rnrur4rtappendrr_rrArBrC)4rrrDrrErFrGrr|rpgswapdegyfdegygybound xcontboundrvrwrxrIr"r r!ryrzr{ degconthpr} degcontfp degcontgpdegdeltaNr9rrunluckyr~deltaarrrdeghpar-degyhprJrKrLrMrNrOrPrQrRs4 rmodgcd_bivariatersR 66QVV  3 33 3 !Q F  66D KKMEB KKMEB R B0A6FJ  q BxbBh/bBh1GGG !QKE !QKE LLNE LLNE0>FJ  q BxbBh/bBh1GGG[[__QTT144 (F [[__UXXuxx 0FI A A  aL!mq ! A!mq ^^A  ^^A A& A& +MMO z !   #A"J BR!,MMO MMO <<>  !59#4 Z ( * ,./ 0 q5   q A^^Aq)FA:++a#003C++a#003C#sA&CZZ\F&..(55a8C   a MM#  FAAv1 4   q5  &z64A F A q ! &//$' '1 F?  F?AF  ]]6 " / / 2 6AF  ;B1 M QV|F  MM"**, 'UU1X dUU1X dDttaxS R A//"(+C//"(+Cc3; O rc |j}|j}|dk(rJt|||j|}|j }||dkDry||dkr ||d<t |S|j |dz } |j |dz } t ||\} }t ||\} }t| | |} | j }| j }| j }|||dz kDry|||dz kr|||dz <t t|}t|}t|||}|}t|dz D]8}|ttt||tt|||z}:|j }t| |z | |z ||dz ||dz z |zdz}||kryd}d}g}g}tt|}|rtj|dd}|j||jd||zsC|jd||z}|j|dz |j|}|j|dz |j|} t!|| |||}!|! |dz }||kDry|!j"r"| j%|j|}|S|!j'|j|}!|j)||j)|!|dz }||k(rnt+||||dz |}t ||d| j%|z}|j |dz }"|"||dz kDry|"||dz kr|"||dz <t |S|ry)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*rN)rrXr(rrr rfrnr4rrrulistrandomsampleremovert_modgcd_multivariate_p is_groundr_rrr)#rrr"degbound contboundrr`rLdeghrrrecontgconthdegcontfdegcontgdegconthrmlcgr}evaltestr<rrr9drhevalpointsr~rfagahadegyhs# rrrs` 66D AAv Aq!  ) )! ,xxz (1+  (1+ HQK" " HHQqSME HHQqSME!QHE1!QHE1 E5! $E||~H||~H||~H)AaC. )AaC. ! !A# a&C a&C Ca EH 1Q3ZCGCa ,c%1+.>BBC||~H EH eh. QqSMIacN *X 5 79: ;A 1u A AJ E %(^F  MM&! $Q ' a  A&* 1%) ZZ!Q  , ,Q / ZZ!Q  , ,Q /$BAx C : FA1u  <<t$11!4AH ]]6 " / / 2! R Q 6)*eT1Q3JA1a #ennT&::AHHQqSMEx!}$x!}$ %1 &&HW Z rc |j|jk(r |jjjsJt||}||S|j}|j}|j \}}|j \}}|jj ||}|jj |j|j}|jj} t|D]I} | |jj t|| jt|| jz} Kt|j|jD cgc]\} } t| | } } } t| }d}d} t|}| |zdk(rt|}| |zdk(r|j!|}|j!|} t#|||| |}|]|j'|j!|}|dk(r|}|}t)|||}||z}||k(s|}|j d}|j+|\}}|j+|\}}|sR|sP|jdkr| }|j'|}|j'||z}|j'||z}|||fS2cc} } w#t$$rd}YGwxYw)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)rrr?rrXr@r+rrr4rrrdegreesrurrrrr rrrC)rrrDrr`rErFrGr,rxr<fdeggdegrrrIr"r r!r-rJrKrLrMrNrOrPrQrRs rmodgcd_multivariater's\ 66QVV  3 33 3 !Q F  66D A KKMEB KKMEB R B KKOOADD!$$ 'E I 1XET[[__U1a[^^U1a[^^DD E36aiik199;2OPJD$D$PHPXI A A  aL!mq ! A!mq ^^A  ^^A  'B8YGB :  ]]5 ! . .q 1 6AF  ;B1 M QV|F  LLN1 UU1X dUU1X dDttaxS R A//"(+C//"(+Cc3; Q  Q"  A  s.K !K KKc|j}t|j|j||j\}}|j ||j |fS)z_ Compute `\frac f g` modulo `p` for two univariate polynomials over `\mathbb Z_p`. )rr to_denserr])rrr"rdensequodenserems r_gf_divrsO 66D ajjlAt{{KHh ??8 $dooh&? ??rc|j}|j}|j}|dz}||z dz }||j} }||j} } | j|kDrVt || |d} | || | zz j |} }| | | | zz j |} } | j|kDrV| | }} |j|kDst|||dk7ry|j}|dk7rR|j||}| j|j |} |j|j |}|j}|| ||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*rN) rrrrrrrr(rrrto_field)cr"rIrrMrDr0s0r1s1r^r~rlcr&fields r!_rational_function_reconstructionrsTJ 66D [[F  A QA A A  B B ))+/b"a #b3r6k//2Bb3r6k//2B ))+/ rqAxxzA~Aq)Q. B Qw b!$ LL  , ,Q / LL  , ,Q / MMOE 8eAh rc,|j}|jD]t\}}|dk(rt|||}|sVy|jj}|j |jD]\} } t| ||} | sy| || <|||<v|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 rN)rrYrrdrop_to_ground) rKr"rIrr`rLrbr5coeffhmonrrGs r$_rational_reconstruction_func_coeffsrs\ A  u 66uaCF[[%%F..q1;;= !Q6q!Q? s  !%#& Hrc|j}t|j|j||j\}}}|j ||j ||j |fS)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`. )rr rrr])rrr"rstrLs r _gf_gcdexrLs[ 66Dqzz|QZZ\1dkkBGAq! ??1 tq14??13E EErc|j}|j|}|j|}|j|j ||gj|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` )rr_ ground_newrr$)rminpolyr"rp_s r_truncrZsT0 66Dt$G  B >>!  '2 / < >t DF !f*gq ))rcV|j}|j|jd|jdf}|j|}|}|j }|j }|j d} t |j|} |j } |r||k\rt |j|} || z|j||z df| zz }|r|j|}|j d}|r|| k\rt |j|j|} |j| |jd|| z f| zz }|r|j|}|j d}|r|| k\r|j }|r||k\r|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*rrV) rr\rWr_rrnrrrr) rrLrr"rzxringr$r'rdegmlchlcmlcrems r_trial_divisionrsB 66D ZZa$,,q/ BZ CFt$G C ZZ\F 88:D >>! D a&//$ C **C &D.C!!$'#g Vd]A$67== ""1%CAfn V,-66t|g}|g}|dk(r%|jj3j4}n.|jjj3j4}|jj6d}t9| ||D]6\}} }!|!|k(s |j;||j;| |||z z}8|j#|}| j;||j;||j;|| dz } t=||||dz |d}"t?|"||||dz }"|"|dk(r|jj@}#|#jj4}$|"jCD]Y}|#jjEtG|$jI|jJjI||#j}$[n|jjj@}#|#jj4}$|"jCD]n}|jCD]Y}%|#jjEtG|$jI|%jJjI||#j}$[p|jM|$j#|}$||"jO|$jQj#|}"tS||"||stS||"||s|"S|rhy)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*rrNT)r)*rrrrrXrrrr\rrrr4rrrrtrrr$_func_field_modgcd_prrYLMtupleget_ringrr3rrrrr itercoeffsr]r rr domain_newras_exprr)&rrrr"rrr`qdomainqringr9rr,r}rrLMlistrr~testgammaaminpolyarrrrrbr5 evalpoints_aheval_arIrrhbLMhbrLr#denrs& rrrsT 66D [[F&.) LL#Aq'155Av++&&(++,,QU3--w~~':':'C'C'E-F JJgJ &E A A KKNT[[^ +E JJEJ E F %(^F  MM&! $Q ' a 6>>!A#q)A-2D>>!A#q)66q9Q>D  !%1a0#GQqS!4 ::xQ0 1Q 6  a1a ( a1a (""b(A 6 : FA1u  7Iiik]aS!A#Y & q5 "  & u8r!u$E"QR&M)A"XXBqrF &s $ 6 %%'++A ##,,.22A FFKKNz5&9 KAr4rz##A&r"a!e    NN1 ! R b Q &lGT1Q3RV W 1Aq%1 E 9  6,,$$C((,,C (hh))&AUAUAW3::+'( ( ,,%%++C((,,C ,))+,A((--fS\\^QWWEUEUEWszz/+,C, , s//23 c"**, - : :1 =q!Wa0AwXY9ZHu x rcv|dkr||z }||j}}||j}}t|dz }t||k\r(||z}||||zz }}||||zz }}t||k\r(t t||k\ry|dkr| | } } n |dkDr||} } ny|j } | | | | 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]_ rrN)rrrintabs get_field) rrIrrrrrrHr^r~rrs r _integer_rational_reconstructionrsH 1u Q  B  B QKE b'U BhR#b&[BR#b&[B b'U   3r7|u AvsRC1 a21    E 8eAh rc|j}t|jtrt}|jj }nt }|j j}|jD]\}}||||}|sy|||<|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)rrrr#_rational_reconstruction_int_coeffsrrrY) rKrIrrLreconstructionrrbr5rs rrrsR A$++~.<!!9  uq&1%  Hrc|j}|j}t|trS|j}|jj |jj }|j |}n,d}|j |jj }|j\}}|j\} }|j||j|z} |j} d} g} g}g} t| } | j| dk(r!|dk(r | | zdk(}n| j| dk(}|rF|j| }|j| }|j| }t|||| }||dk(r |jS|jgdg|zz}|dkDrO|jD]<\}}|d|dk(s|j t#|ddkDs.|j |dd>|}| }t%| ||D]\}}}||k(s t'||||}||z}!| j)| |j)||j)|t+|||}|~|dk(r|j-d}ni|jj}|j/D]/}|jj1||j-d}1|j3|}|j5|}|jd}t7|j3|||st7|j3| ||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 rrr*N)rrrrrXr\rr@rrrrrrrrYrrrrrr clear_denomsrrrr_r)rrrrrr`QQdomainQQringrErFr,r}r"primeshplistrrr r!minpolypr-rrbr5rKrIr8r7LMhqrLr s r_func_field_modgcd_mr's3D 66D [[F&.) LL;;$$FMM,C,C,E$F8, 4;;#8#8#:; KKMEB KKMEB KKNT[[^ +E JJE A F F F  aL   a A %  6AIND&&q)Q.D   ^^A  ^^A ''* !"b(A 6 :  788Oiik]aSU " q5 "  & u8r!u$E"QR&M)A"XXBqrF & vvv6 KAr4rzCBAqQQ   a b b 0Q ? :  6!!$A--##C Fmm''U-?-?-A!-DE F c"A JJt  KKM!  R 0!W= ALL,a 9H rc|j}t|jtr|jj}n |j}|j}|j D]6}|j D]!}|s|j||j}#8|jD]\}}|j }|jj}t|jtr|j|dd}t|} t| D]Z} || s |j|| |z|z}|d| | z dz f|vr|||d| | z dz f<C||d| | z dz fxx|z cc<\|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)rrrrrrto_listr denominatorrYrlenr4convert) rrf_rr r5rrbrIr9r<s r _to_ZZ_polyr"sl2 B$++~.## **C5 5Ajjamm4 55  / u  KKOO dkk> 2 E!"I&A Jq /AQxNN58c>2Q6!Hac!e$B.,-Ba!A#a%()a!A#a%()Q.) // Irc|j}|j}t|jjtrt|j D]_\}}|j D]G\}}|df|z}||j|gdg|dzz} ||vr| ||<;||xx| z cc<Ia|S|j D]D\}}|df}||j|gdg|dzz} ||vr| ||<8||xx| z cc<F|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}]` rr*)rrrrrrY) rrrr!rbr5rcoefrIrs r _to_ANP_polyr%s#0[[F B!&&--0KKM LE5"__.  T1XK#%FMM$/0A3uQx<?@B;BqEqEQJE  ( IKKM LE5q A e,-E!H <=A{11   Ircv|j}|jD]\}}|j|||<|S)zo Change representation of the minimal polynomial from ``DMP`` to ``PolyElement`` for a given ring. )rtermsr)rrminpoly_rbr5s r_minpoly_from_denser)0s? yyH - u++e,- Orc|j}|jtd|j}|jj}||j }|j }|jD]&}t||d}||jk(s"||fcS||j|j|fS)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) rrr4rXrrrrfunc_field_modgcdrr^r_)rfringrr#r!rcr5s r_primitive_in_x0r-=s FFE 5  q%++!6 7D ++  C aiik B 88D u-a0 377?7N t}}U+, ,,rcN|j}|j}|j}||jk(r |jsJt ||}||St d}|j |j|fz|jj}|dk(rjt||}t||} |jdj|jj} t|| | } t| |} nt!|\} }t!|\} }t#| | d}|j$t'd|}t||}t||} t)|j|jd} t|| | } t| |} t!| \}} | |j+|z} || j+|z}|| j+|z}| j-| j.} | |j1| |j1| fS)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)rWrr*r)rrrX is_Algebraicrrr\rWrr"rr]modrrr%r-r+rr4r)r_rArr^)rrrrr9rDr/ZZringr!g_rrLcontx0fcontx0gcontx0hZZring_contx0h_s rr+r+RsP 66D [[F A 166>f111 1 !Q F   c A ZZ t 3FMM,>,@A R 1 D !&a( %a( #GW5a8'&''q!5 G $ G $%fjj',,q/B R 1 D !&q) ! W  d ## W  d ## W  d ## QTTA aeeAha  r)F)N)3sympy.core.symbolr sympy.ntheoryrsympy.ntheory.modularrsympy.polys.domainsrsympy.polys.galoistoolsrr r r r sympy.polys.polyerrorsr mpmathrrrr(r/r=rSrfrjrnrrrrrrrrrrrrrrrrrrrrr"r%r)r-r+rrrAs##%.443 ,?.B>B~B:.z-`2j H5V`F>BQhVrPf@?DC L F@>5*pBJ cL=@: zYx7t0f -*T!r