K iHdZddlmZmZddlmZddlmZddlm Z m Z m Z m Z ddl mZddlmZmZddlmZdd lmZmZedd Zd Zd ZdZdZdZdZdZdZdZ dZ!dZ"dZ#GddZ$eGddeZ%y )z@Tools and arithmetics for monomials of distributed polynomials. )combinations_with_replacementproduct)dedent)cacheit)MulSTuplesympify)ExactQuotientFailed)PicklableWithSlotsdict_from_expr)public) is_sequenceiterableNc#Ktrt|}t|k7r tddg|znLts tdt|k7r tdtdDr tdtfdt |Dr tdg}t |D]5\}}}|j t ||d zDcgc]}||z c}7t|D] } t| y} | dkr td d} ndkr td } | | kDry|r| dk(rtjyt|tjgz}td |Dr t|| } n t|| } t} | | z }| D]4}d}|D]}|d k(s |d z }||ks| jt|6| Ed{ycc}w7 w)a ``max_degrees`` and ``min_degrees`` are either both integers or both lists. Unless otherwise specified, ``min_degrees`` is either ``0`` or ``[0, ..., 0]``. A generator of all monomials ``monom`` is returned, such that either ``min_degree <= total_degree(monom) <= max_degree``, or ``min_degrees[i] <= degree_list(monom)[i] <= max_degrees[i]``, for all ``i``. Case I. ``max_degrees`` and ``min_degrees`` are both integers ============================================================= Given a set of variables $V$ and a min_degree $N$ and a max_degree $M$ generate a set of monomials of degree less than or equal to $N$ and greater than or equal to $M$. The total number of monomials in commutative variables is huge and is given by the following formula if $M = 0$: .. math:: \frac{(\#V + N)!}{\#V! N!} For example if we would like to generate a dense polynomial of a total degree $N = 50$ and $M = 0$, which is the worst case, in 5 variables, assuming that exponents and all of coefficients are 32-bit long and stored in an array we would need almost 80 GiB of memory! Fortunately most polynomials, that we will encounter, are sparse. Consider monomials in commutative variables $x$ and $y$ and non-commutative variables $a$ and $b$:: >>> from sympy import symbols >>> from sympy.polys.monomials import itermonomials >>> from sympy.polys.orderings import monomial_key >>> from sympy.abc import x, y >>> sorted(itermonomials([x, y], 2), key=monomial_key('grlex', [y, x])) [1, x, y, x**2, x*y, y**2] >>> sorted(itermonomials([x, y], 3), key=monomial_key('grlex', [y, x])) [1, x, y, x**2, x*y, y**2, x**3, x**2*y, x*y**2, y**3] >>> a, b = symbols('a, b', commutative=False) >>> set(itermonomials([a, b, x], 2)) {1, a, a**2, b, b**2, x, x**2, a*b, b*a, x*a, x*b} >>> sorted(itermonomials([x, y], 2, 1), key=monomial_key('grlex', [y, x])) [x, y, x**2, x*y, y**2] Case II. ``max_degrees`` and ``min_degrees`` are both lists =========================================================== If ``max_degrees = [d_1, ..., d_n]`` and ``min_degrees = [e_1, ..., e_n]``, the number of monomials generated is: .. math:: (d_1 - e_1 + 1) (d_2 - e_2 + 1) \cdots (d_n - e_n + 1) Let us generate all monomials ``monom`` in variables $x$ and $y$ such that ``[1, 2][i] <= degree_list(monom)[i] <= [2, 4][i]``, ``i = 0, 1`` :: >>> from sympy import symbols >>> from sympy.polys.monomials import itermonomials >>> from sympy.polys.orderings import monomial_key >>> from sympy.abc import x, y >>> sorted(itermonomials([x, y], [2, 4], [1, 2]), reverse=True, key=monomial_key('lex', [x, y])) [x**2*y**4, x**2*y**3, x**2*y**2, x*y**4, x*y**3, x*y**2] zArgument sizes do not matchNrzmin_degrees is not a listc3&K|] }|dk ywrN).0is [/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/polys/monomials.py z itermonomials..cs.Q1q5.z+min_degrees cannot contain negative numbersc34K|]}||kDywNr)rr max_degrees min_degreess rrz itermonomials..esA1{1~ A.Asz2min_degrees[i] must be <= max_degrees[i] for all izmax_degrees cannot be negativezmin_degrees cannot be negativec34K|]}|jywr)is_commutative)rvariables rrz itermonomials..}sA8x&&As)repeat)rlen ValueErroranyrangezipappendrrrOnelistallrsetadd) variablesrrn power_listsvarmin_dmax_drpowers max_degree min_degreeit monomials_setditemcountr!s `` r itermonomialsr<s'T;  N { q :; ;  #a%K[)89 9;1$ !>??.+.. !NOO AaA AQR R !$Y [!I J C   eUQY0GH1QH I J{+ Fv,  ! >=> >  JQ !ABB$J  " J!O%%K Oquug- AyA A.y*EB:6B  # .DE  .q=QJE5y  . !!#t*- .!  G IF !s+C!G>% G7 1CG> G>!G>1G<2 G>cHddlm}|||z||z ||z S)aW Computes the number of monomials. The number of monomials is given by the following formula: .. math:: \frac{(\#V + N)!}{\#V! N!} where `N` is a total degree and `V` is a set of variables. Examples ======== >>> from sympy.polys.monomials import itermonomials, monomial_count >>> from sympy.polys.orderings import monomial_key >>> from sympy.abc import x, y >>> monomial_count(2, 2) 6 >>> M = list(itermonomials([x, y], 2)) >>> sorted(M, key=monomial_key('grlex', [y, x])) [1, x, y, x**2, x*y, y**2] >>> len(M) 6 r) factorial)(sympy.functions.combinatorial.factorialsr>)VNr>s rmonomial_countrBs)<C QU il *Yq\ 99cdtt||Dcgc] \}}||z c}}Scc}}w)a% Multiplication of tuples representing monomials. Examples ======== Lets multiply `x**3*y**4*z` with `x*y**2`:: >>> from sympy.polys.monomials import monomial_mul >>> monomial_mul((3, 4, 1), (1, 2, 0)) (4, 6, 1) which gives `x**4*y**5*z`. tupler'ABabs r monomial_mulrLs+" SAY0TQ1q50 110, cVt||}td|Dr t|Sy)a Division of tuples representing monomials. Examples ======== Lets divide `x**3*y**4*z` by `x*y**2`:: >>> from sympy.polys.monomials import monomial_div >>> monomial_div((3, 4, 1), (1, 2, 0)) (2, 2, 1) which gives `x**2*y**2*z`. However:: >>> monomial_div((3, 4, 1), (1, 2, 2)) is None True `x*y**2*z**2` does not divide `x**3*y**4*z`. c3&K|] }|dk\ ywrr)rcs rrzmonomial_div..s a16 rN) monomial_ldivr+rF)rHrICs r monomial_divrSs*, aA 1 QxrCcdtt||Dcgc] \}}||z  c}}Scc}}w)a Division of tuples representing monomials. Examples ======== Lets divide `x**3*y**4*z` by `x*y**2`:: >>> from sympy.polys.monomials import monomial_ldiv >>> monomial_ldiv((3, 4, 1), (1, 2, 0)) (2, 2, 1) which gives `x**2*y**2*z`. >>> monomial_ldiv((3, 4, 1), (1, 2, 2)) (2, 2, -1) which gives `x**2*y**2*z**-1`. rErGs rrQrQs+, SAY0TQ1q50 110rMcDt|Dcgc]}||z c}Scc}w)z%Return the n-th pow of the monomial. )rF)rHr/rJs r monomial_powrVs #11Q3# $$#s c rtt||Dcgc]\}}t||c}}Scc}}w)a. Greatest common divisor of tuples representing monomials. Examples ======== Lets compute GCD of `x*y**4*z` and `x**3*y**2`:: >>> from sympy.polys.monomials import monomial_gcd >>> monomial_gcd((1, 4, 1), (3, 2, 0)) (1, 2, 0) which gives `x*y**2`. )rFr'minrGs r monomial_gcdrY-" Q4A3q!94 5543 c rtt||Dcgc]\}}t||c}}Scc}}w)a1 Least common multiple of tuples representing monomials. Examples ======== Lets compute LCM of `x*y**4*z` and `x**3*y**2`:: >>> from sympy.polys.monomials import monomial_lcm >>> monomial_lcm((1, 4, 1), (3, 2, 0)) (3, 4, 1) which gives `x**3*y**4*z`. )rFr'maxrGs r monomial_lcmr^rZr[c:tdt||DS)z Does there exist a monomial X such that XA == B? Examples ======== >>> from sympy.polys.monomials import monomial_divides >>> monomial_divides((1, 2), (3, 4)) True >>> monomial_divides((1, 2), (0, 2)) False c3,K|] \}}||kywrr)rrJrKs rrz#monomial_divides...s,$!QqAv,s)r+r')rHrIs rmonomial_dividesra!s ,#a), ,,rCct|d}|ddD]'}t|D]\}}t|||||<)t|S)a Returns maximal degree for each variable in a set of monomials. Examples ======== Consider monomials `x**3*y**4*z**5`, `y**5*z` and `x**6*y**3*z**9`. We wish to find out what is the maximal degree for each of `x`, `y` and `z` variables:: >>> from sympy.polys.monomials import monomial_max >>> monomial_max((3,4,5), (0,5,1), (6,3,9)) (6, 5, 9) rrN)r* enumerater]rFmonomsMrArr/s r monomial_maxrg0[" VAYA ABZ aL DAqqtQ>> from sympy.polys.monomials import monomial_min >>> monomial_min((3,4,5), (0,5,1), (6,3,9)) (0, 3, 1) rrN)r*rcrXrFrds r monomial_minrjIrhrCct|S)z Returns the total degree of a monomial. Examples ======== The total degree of `xy^2` is 3: >>> from sympy.polys.monomials import monomial_deg >>> monomial_deg((1, 2)) 3 )sum)rfs r monomial_degrmbs  q6MrCc|\}}|\}}t||}|jr|||j||fSy|||zs||j||fSy)z,Division of two terms in over a ring/field. N)rSis_Fieldquo)rJrKdomaina_lma_lcb_lmb_lcmonoms rterm_divrwqsjJD$JD$ t $E   &**T400 0 &**T400 0rCceZdZdZefdZdZdZdZedZ edZ edZ ed Z ed Z ed Zed ZxZS) MonomialOpsz6Code generator of fast monomial arithmetic functions. c4t||}||_|Sr)super__new__ngens)clsr}obj __class__s rr|zMonomialOps.__new__sgoc"  rCc|jfSr)r}selfs r__getnewargs__zMonomialOps.__getnewargs__s }rCc(i}t||||Sr)exec)rcodenamenss r_buildzMonomialOps._builds  T2$xrCcZt|jDcgc]}|| c}Scc}wr)r&r})rrrs r_varszMonomialOps._varss$-24::->@4#@@@s (cDd}td}|jd}|jd}t||Dcgc] \}}|d|}}}||dj|dj|dj|dz}|j ||Scc}}w)NrLs def %(name)s(A, B): (%(A)s,) = A (%(B)s,) = B return (%(AB)s,) rJrK + , rrHrIABrrr'joinr rrtemplaterHrIrJrKrrs rmulzMonomialOps.muls   JJsO JJsO.1!Qi 9daAq! 9 94diil1UYU^U^_aUbcc{{4&&:Bcd}td}|jd}|Dcgc]}d|z }}||dj|dj|dz}|j||Scc}w)NrVzZ def %(name)s(A, k): (%(A)s,) = A return (%(Ak)s,) rJz%s*kr)rrHAk)rrrr)rrrrHrJrrs rpowzMonomialOps.powss   JJsO#$ &avz & &4diil$))B-PP{{4&&'s A*cFd}td}|jd}|jd}t||Dcgc] \}}|d|d}}}||dj|dj|dj|dz}|j ||Scc}}w) Nmonomial_mulpowzw def %(name)s(A, B, k): (%(A)s,) = A (%(B)s,) = B return (%(ABk)s,) rJrKrz*kr)rrHrIABkr) rrrrHrIrJrKrrs rmulpowzMonomialOps.mulpows    JJsO JJsO14Q<Aq!$<<4diil1VZV_V_`cVdee{{4&&=sBcDd}td}|jd}|jd}t||Dcgc] \}}|d|}}}||dj|dj|dj|dz}|j ||Scc}}w)NrQrrJrKz - rrrrs rldivzMonomialOps.ldivs   JJsO JJsO.1!Qi 9daAq! 9 94diil1UYU^U^_aUbcc{{4&&:rcd}td}|jd}|jd}t|jDcgc] }dd|iz }}|jd}||dj |dj |d j |dj |d z}|j ||Scc}w) NrSz def %(name)s(A, B): (%(A)s,) = A (%(B)s,) = B %(RAB)s return (%(R)s,) rJrKz7r%(i)s = a%(i)s - b%(i)s if r%(i)s < 0: return Nonerrrz )rrHrIRABR)rrr&r}rr) rrrrHrIrrrrs rdivzMonomialOps.divs   JJsO JJsO_deieoeo_prZ[JcSTXUrr JJsO4diil1V^VcVcdgVhosoxoxyzo{||{{4&&ssCc Pd}td}|jd}|jd}t||Dcgc]\}}|d|d|d|}}}||dj|dj|dj|d z}|j ||Scc}}w) Nr^rrJrK if z >=  else rrrrs rlcmzMonomialOps.lcm   JJsO JJsOCFq!9 N41a1aA6 N N4diil1UYU^U^_aUbcc{{4&&OB"c Pd}td}|jd}|jd}t||Dcgc]\}}|d|d|d|}}}||dj|dj|dj|d z}|j ||Scc}}w) NrYrrJrKrz <= rrrrrs rgcdzMonomialOps.gcdrr)__name__ __module__ __qualname____doc__rr|rrrrrrrrrr __classcell__)rs@rryrys@    A  '  '  '  '  '  '  '  ' ' '   '  '  '  'rCrycveZdZdZdZddZddZdZdZdZ d Z d Z d Z d Z d ZdZdZeZdZdZdZy)Monomialz9Class representing a monomial, i.e. a product of powers. ) exponentsgensNc^t|s}tt||\}}t|dk(r>""rCc,t|jSr)iterrrs r__iter__zMonomial.__iter__sDNN##rCc |j|Sr)r)rr:s r __getitem__zMonomial.__getitem__s~~d##rCcnt|jj|j|jfSr)hashrrrrrs r__hash__zMonomial.__hash__s&T^^,,dnndiiHIIrCc |jrGdjt|j|jDcgc] \}}|d|c}}S|jj d|jdScc}}w)N*z**())rrr'rrr)rgenexps r__str__zMonomial.__str__ s] 9988C SWSaSaDbdS#s3de e#~~66G GesA: c|xs |j}|std|ztt||jDcgc] \}}||z c}}Scc}}w)z3Convert a monomial instance to a SymPy expression. z5Cannot convert %s to an expression without generators)rr$rr'r)rrrrs ras_exprzMonomial.as_expr&sX tyyG$NP Ps4/HJ83c3hJKKJsA ct|tr |j}nt|ttfr|}ny|j|k(S)NF) isinstancerrrFr rotherrs r__eq__zMonomial.__eq__0s: eX &I u~ .I~~**rCc||k( Srr)rrs r__ne__zMonomial.__ne__:s5=  rCct|tr |j}nt|ttfr|}nt |j t|j|Sr)rrrrFr NotImplementedErrorrrLrs r__mul__zMonomial.__mul__=sH eX &I u~ .I% %||LCDDrCct|tr |j}nt|ttfr|}nt t |j|}||j|St|t|r) rrrrFr rrSrr )rrrresults r __truediv__zMonomial.__truediv__Gsd eX &I u~ .I% %dnni8  <<' '%dHUO< rsF=$--6D";}!}!~:B2&:20%6&6& -22 ${'{'zsE!sEsErC