123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881 |
- """Basic tools for dense recursive polynomials in ``K[x]`` or ``K[X]``. """
- from sympy.core.numbers import oo
- from sympy.core import igcd
- from sympy.polys.monomials import monomial_min, monomial_div
- from sympy.polys.orderings import monomial_key
- import random
- def poly_LC(f, K):
- """
- Return leading coefficient of ``f``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import poly_LC
- >>> poly_LC([], ZZ)
- 0
- >>> poly_LC([ZZ(1), ZZ(2), ZZ(3)], ZZ)
- 1
- """
- if not f:
- return K.zero
- else:
- return f[0]
- def poly_TC(f, K):
- """
- Return trailing coefficient of ``f``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import poly_TC
- >>> poly_TC([], ZZ)
- 0
- >>> poly_TC([ZZ(1), ZZ(2), ZZ(3)], ZZ)
- 3
- """
- if not f:
- return K.zero
- else:
- return f[-1]
- dup_LC = dmp_LC = poly_LC
- dup_TC = dmp_TC = poly_TC
- def dmp_ground_LC(f, u, K):
- """
- Return the ground leading coefficient.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_ground_LC
- >>> f = ZZ.map([[[1], [2, 3]]])
- >>> dmp_ground_LC(f, 2, ZZ)
- 1
- """
- while u:
- f = dmp_LC(f, K)
- u -= 1
- return dup_LC(f, K)
- def dmp_ground_TC(f, u, K):
- """
- Return the ground trailing coefficient.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_ground_TC
- >>> f = ZZ.map([[[1], [2, 3]]])
- >>> dmp_ground_TC(f, 2, ZZ)
- 3
- """
- while u:
- f = dmp_TC(f, K)
- u -= 1
- return dup_TC(f, K)
- def dmp_true_LT(f, u, K):
- """
- Return the leading term ``c * x_1**n_1 ... x_k**n_k``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_true_LT
- >>> f = ZZ.map([[4], [2, 0], [3, 0, 0]])
- >>> dmp_true_LT(f, 1, ZZ)
- ((2, 0), 4)
- """
- monom = []
- while u:
- monom.append(len(f) - 1)
- f, u = f[0], u - 1
- if not f:
- monom.append(0)
- else:
- monom.append(len(f) - 1)
- return tuple(monom), dup_LC(f, K)
- def dup_degree(f):
- """
- Return the leading degree of ``f`` in ``K[x]``.
- Note that the degree of 0 is negative infinity (the SymPy object -oo).
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_degree
- >>> f = ZZ.map([1, 2, 0, 3])
- >>> dup_degree(f)
- 3
- """
- if not f:
- return -oo
- return len(f) - 1
- def dmp_degree(f, u):
- """
- Return the leading degree of ``f`` in ``x_0`` in ``K[X]``.
- Note that the degree of 0 is negative infinity (the SymPy object -oo).
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_degree
- >>> dmp_degree([[[]]], 2)
- -oo
- >>> f = ZZ.map([[2], [1, 2, 3]])
- >>> dmp_degree(f, 1)
- 1
- """
- if dmp_zero_p(f, u):
- return -oo
- else:
- return len(f) - 1
- def _rec_degree_in(g, v, i, j):
- """Recursive helper function for :func:`dmp_degree_in`."""
- if i == j:
- return dmp_degree(g, v)
- v, i = v - 1, i + 1
- return max([ _rec_degree_in(c, v, i, j) for c in g ])
- def dmp_degree_in(f, j, u):
- """
- Return the leading degree of ``f`` in ``x_j`` in ``K[X]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_degree_in
- >>> f = ZZ.map([[2], [1, 2, 3]])
- >>> dmp_degree_in(f, 0, 1)
- 1
- >>> dmp_degree_in(f, 1, 1)
- 2
- """
- if not j:
- return dmp_degree(f, u)
- if j < 0 or j > u:
- raise IndexError("0 <= j <= %s expected, got %s" % (u, j))
- return _rec_degree_in(f, u, 0, j)
- def _rec_degree_list(g, v, i, degs):
- """Recursive helper for :func:`dmp_degree_list`."""
- degs[i] = max(degs[i], dmp_degree(g, v))
- if v > 0:
- v, i = v - 1, i + 1
- for c in g:
- _rec_degree_list(c, v, i, degs)
- def dmp_degree_list(f, u):
- """
- Return a list of degrees of ``f`` in ``K[X]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_degree_list
- >>> f = ZZ.map([[1], [1, 2, 3]])
- >>> dmp_degree_list(f, 1)
- (1, 2)
- """
- degs = [-oo]*(u + 1)
- _rec_degree_list(f, u, 0, degs)
- return tuple(degs)
- def dup_strip(f):
- """
- Remove leading zeros from ``f`` in ``K[x]``.
- Examples
- ========
- >>> from sympy.polys.densebasic import dup_strip
- >>> dup_strip([0, 0, 1, 2, 3, 0])
- [1, 2, 3, 0]
- """
- if not f or f[0]:
- return f
- i = 0
- for cf in f:
- if cf:
- break
- else:
- i += 1
- return f[i:]
- def dmp_strip(f, u):
- """
- Remove leading zeros from ``f`` in ``K[X]``.
- Examples
- ========
- >>> from sympy.polys.densebasic import dmp_strip
- >>> dmp_strip([[], [0, 1, 2], [1]], 1)
- [[0, 1, 2], [1]]
- """
- if not u:
- return dup_strip(f)
- if dmp_zero_p(f, u):
- return f
- i, v = 0, u - 1
- for c in f:
- if not dmp_zero_p(c, v):
- break
- else:
- i += 1
- if i == len(f):
- return dmp_zero(u)
- else:
- return f[i:]
- def _rec_validate(f, g, i, K):
- """Recursive helper for :func:`dmp_validate`."""
- if not isinstance(g, list):
- if K is not None and not K.of_type(g):
- raise TypeError("%s in %s in not of type %s" % (g, f, K.dtype))
- return {i - 1}
- elif not g:
- return {i}
- else:
- levels = set()
- for c in g:
- levels |= _rec_validate(f, c, i + 1, K)
- return levels
- def _rec_strip(g, v):
- """Recursive helper for :func:`_rec_strip`."""
- if not v:
- return dup_strip(g)
- w = v - 1
- return dmp_strip([ _rec_strip(c, w) for c in g ], v)
- def dmp_validate(f, K=None):
- """
- Return the number of levels in ``f`` and recursively strip it.
- Examples
- ========
- >>> from sympy.polys.densebasic import dmp_validate
- >>> dmp_validate([[], [0, 1, 2], [1]])
- ([[1, 2], [1]], 1)
- >>> dmp_validate([[1], 1])
- Traceback (most recent call last):
- ...
- ValueError: invalid data structure for a multivariate polynomial
- """
- levels = _rec_validate(f, f, 0, K)
- u = levels.pop()
- if not levels:
- return _rec_strip(f, u), u
- else:
- raise ValueError(
- "invalid data structure for a multivariate polynomial")
- def dup_reverse(f):
- """
- Compute ``x**n * f(1/x)``, i.e.: reverse ``f`` in ``K[x]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_reverse
- >>> f = ZZ.map([1, 2, 3, 0])
- >>> dup_reverse(f)
- [3, 2, 1]
- """
- return dup_strip(list(reversed(f)))
- def dup_copy(f):
- """
- Create a new copy of a polynomial ``f`` in ``K[x]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_copy
- >>> f = ZZ.map([1, 2, 3, 0])
- >>> dup_copy([1, 2, 3, 0])
- [1, 2, 3, 0]
- """
- return list(f)
- def dmp_copy(f, u):
- """
- Create a new copy of a polynomial ``f`` in ``K[X]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_copy
- >>> f = ZZ.map([[1], [1, 2]])
- >>> dmp_copy(f, 1)
- [[1], [1, 2]]
- """
- if not u:
- return list(f)
- v = u - 1
- return [ dmp_copy(c, v) for c in f ]
- def dup_to_tuple(f):
- """
- Convert `f` into a tuple.
- This is needed for hashing. This is similar to dup_copy().
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_copy
- >>> f = ZZ.map([1, 2, 3, 0])
- >>> dup_copy([1, 2, 3, 0])
- [1, 2, 3, 0]
- """
- return tuple(f)
- def dmp_to_tuple(f, u):
- """
- Convert `f` into a nested tuple of tuples.
- This is needed for hashing. This is similar to dmp_copy().
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_to_tuple
- >>> f = ZZ.map([[1], [1, 2]])
- >>> dmp_to_tuple(f, 1)
- ((1,), (1, 2))
- """
- if not u:
- return tuple(f)
- v = u - 1
- return tuple(dmp_to_tuple(c, v) for c in f)
- def dup_normal(f, K):
- """
- Normalize univariate polynomial in the given domain.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_normal
- >>> dup_normal([0, 1.5, 2, 3], ZZ)
- [1, 2, 3]
- """
- return dup_strip([ K.normal(c) for c in f ])
- def dmp_normal(f, u, K):
- """
- Normalize a multivariate polynomial in the given domain.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_normal
- >>> dmp_normal([[], [0, 1.5, 2]], 1, ZZ)
- [[1, 2]]
- """
- if not u:
- return dup_normal(f, K)
- v = u - 1
- return dmp_strip([ dmp_normal(c, v, K) for c in f ], u)
- def dup_convert(f, K0, K1):
- """
- Convert the ground domain of ``f`` from ``K0`` to ``K1``.
- Examples
- ========
- >>> from sympy.polys.rings import ring
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_convert
- >>> R, x = ring("x", ZZ)
- >>> dup_convert([R(1), R(2)], R.to_domain(), ZZ)
- [1, 2]
- >>> dup_convert([ZZ(1), ZZ(2)], ZZ, R.to_domain())
- [1, 2]
- """
- if K0 is not None and K0 == K1:
- return f
- else:
- return dup_strip([ K1.convert(c, K0) for c in f ])
- def dmp_convert(f, u, K0, K1):
- """
- Convert the ground domain of ``f`` from ``K0`` to ``K1``.
- Examples
- ========
- >>> from sympy.polys.rings import ring
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_convert
- >>> R, x = ring("x", ZZ)
- >>> dmp_convert([[R(1)], [R(2)]], 1, R.to_domain(), ZZ)
- [[1], [2]]
- >>> dmp_convert([[ZZ(1)], [ZZ(2)]], 1, ZZ, R.to_domain())
- [[1], [2]]
- """
- if not u:
- return dup_convert(f, K0, K1)
- if K0 is not None and K0 == K1:
- return f
- v = u - 1
- return dmp_strip([ dmp_convert(c, v, K0, K1) for c in f ], u)
- def dup_from_sympy(f, K):
- """
- Convert the ground domain of ``f`` from SymPy to ``K``.
- Examples
- ========
- >>> from sympy import S
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_from_sympy
- >>> dup_from_sympy([S(1), S(2)], ZZ) == [ZZ(1), ZZ(2)]
- True
- """
- return dup_strip([ K.from_sympy(c) for c in f ])
- def dmp_from_sympy(f, u, K):
- """
- Convert the ground domain of ``f`` from SymPy to ``K``.
- Examples
- ========
- >>> from sympy import S
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_from_sympy
- >>> dmp_from_sympy([[S(1)], [S(2)]], 1, ZZ) == [[ZZ(1)], [ZZ(2)]]
- True
- """
- if not u:
- return dup_from_sympy(f, K)
- v = u - 1
- return dmp_strip([ dmp_from_sympy(c, v, K) for c in f ], u)
- def dup_nth(f, n, K):
- """
- Return the ``n``-th coefficient of ``f`` in ``K[x]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_nth
- >>> f = ZZ.map([1, 2, 3])
- >>> dup_nth(f, 0, ZZ)
- 3
- >>> dup_nth(f, 4, ZZ)
- 0
- """
- if n < 0:
- raise IndexError("'n' must be non-negative, got %i" % n)
- elif n >= len(f):
- return K.zero
- else:
- return f[dup_degree(f) - n]
- def dmp_nth(f, n, u, K):
- """
- Return the ``n``-th coefficient of ``f`` in ``K[x]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_nth
- >>> f = ZZ.map([[1], [2], [3]])
- >>> dmp_nth(f, 0, 1, ZZ)
- [3]
- >>> dmp_nth(f, 4, 1, ZZ)
- []
- """
- if n < 0:
- raise IndexError("'n' must be non-negative, got %i" % n)
- elif n >= len(f):
- return dmp_zero(u - 1)
- else:
- return f[dmp_degree(f, u) - n]
- def dmp_ground_nth(f, N, u, K):
- """
- Return the ground ``n``-th coefficient of ``f`` in ``K[x]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_ground_nth
- >>> f = ZZ.map([[1], [2, 3]])
- >>> dmp_ground_nth(f, (0, 1), 1, ZZ)
- 2
- """
- v = u
- for n in N:
- if n < 0:
- raise IndexError("`n` must be non-negative, got %i" % n)
- elif n >= len(f):
- return K.zero
- else:
- d = dmp_degree(f, v)
- if d == -oo:
- d = -1
- f, v = f[d - n], v - 1
- return f
- def dmp_zero_p(f, u):
- """
- Return ``True`` if ``f`` is zero in ``K[X]``.
- Examples
- ========
- >>> from sympy.polys.densebasic import dmp_zero_p
- >>> dmp_zero_p([[[[[]]]]], 4)
- True
- >>> dmp_zero_p([[[[[1]]]]], 4)
- False
- """
- while u:
- if len(f) != 1:
- return False
- f = f[0]
- u -= 1
- return not f
- def dmp_zero(u):
- """
- Return a multivariate zero.
- Examples
- ========
- >>> from sympy.polys.densebasic import dmp_zero
- >>> dmp_zero(4)
- [[[[[]]]]]
- """
- r = []
- for i in range(u):
- r = [r]
- return r
- def dmp_one_p(f, u, K):
- """
- Return ``True`` if ``f`` is one in ``K[X]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_one_p
- >>> dmp_one_p([[[ZZ(1)]]], 2, ZZ)
- True
- """
- return dmp_ground_p(f, K.one, u)
- def dmp_one(u, K):
- """
- Return a multivariate one over ``K``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_one
- >>> dmp_one(2, ZZ)
- [[[1]]]
- """
- return dmp_ground(K.one, u)
- def dmp_ground_p(f, c, u):
- """
- Return True if ``f`` is constant in ``K[X]``.
- Examples
- ========
- >>> from sympy.polys.densebasic import dmp_ground_p
- >>> dmp_ground_p([[[3]]], 3, 2)
- True
- >>> dmp_ground_p([[[4]]], None, 2)
- True
- """
- if c is not None and not c:
- return dmp_zero_p(f, u)
- while u:
- if len(f) != 1:
- return False
- f = f[0]
- u -= 1
- if c is None:
- return len(f) <= 1
- else:
- return f == [c]
- def dmp_ground(c, u):
- """
- Return a multivariate constant.
- Examples
- ========
- >>> from sympy.polys.densebasic import dmp_ground
- >>> dmp_ground(3, 5)
- [[[[[[3]]]]]]
- >>> dmp_ground(1, -1)
- 1
- """
- if not c:
- return dmp_zero(u)
- for i in range(u + 1):
- c = [c]
- return c
- def dmp_zeros(n, u, K):
- """
- Return a list of multivariate zeros.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_zeros
- >>> dmp_zeros(3, 2, ZZ)
- [[[[]]], [[[]]], [[[]]]]
- >>> dmp_zeros(3, -1, ZZ)
- [0, 0, 0]
- """
- if not n:
- return []
- if u < 0:
- return [K.zero]*n
- else:
- return [ dmp_zero(u) for i in range(n) ]
- def dmp_grounds(c, n, u):
- """
- Return a list of multivariate constants.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_grounds
- >>> dmp_grounds(ZZ(4), 3, 2)
- [[[[4]]], [[[4]]], [[[4]]]]
- >>> dmp_grounds(ZZ(4), 3, -1)
- [4, 4, 4]
- """
- if not n:
- return []
- if u < 0:
- return [c]*n
- else:
- return [ dmp_ground(c, u) for i in range(n) ]
- def dmp_negative_p(f, u, K):
- """
- Return ``True`` if ``LC(f)`` is negative.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_negative_p
- >>> dmp_negative_p([[ZZ(1)], [-ZZ(1)]], 1, ZZ)
- False
- >>> dmp_negative_p([[-ZZ(1)], [ZZ(1)]], 1, ZZ)
- True
- """
- return K.is_negative(dmp_ground_LC(f, u, K))
- def dmp_positive_p(f, u, K):
- """
- Return ``True`` if ``LC(f)`` is positive.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_positive_p
- >>> dmp_positive_p([[ZZ(1)], [-ZZ(1)]], 1, ZZ)
- True
- >>> dmp_positive_p([[-ZZ(1)], [ZZ(1)]], 1, ZZ)
- False
- """
- return K.is_positive(dmp_ground_LC(f, u, K))
- def dup_from_dict(f, K):
- """
- Create a ``K[x]`` polynomial from a ``dict``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_from_dict
- >>> dup_from_dict({(0,): ZZ(7), (2,): ZZ(5), (4,): ZZ(1)}, ZZ)
- [1, 0, 5, 0, 7]
- >>> dup_from_dict({}, ZZ)
- []
- """
- if not f:
- return []
- n, h = max(f.keys()), []
- if isinstance(n, int):
- for k in range(n, -1, -1):
- h.append(f.get(k, K.zero))
- else:
- (n,) = n
- for k in range(n, -1, -1):
- h.append(f.get((k,), K.zero))
- return dup_strip(h)
- def dup_from_raw_dict(f, K):
- """
- Create a ``K[x]`` polynomial from a raw ``dict``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_from_raw_dict
- >>> dup_from_raw_dict({0: ZZ(7), 2: ZZ(5), 4: ZZ(1)}, ZZ)
- [1, 0, 5, 0, 7]
- """
- if not f:
- return []
- n, h = max(f.keys()), []
- for k in range(n, -1, -1):
- h.append(f.get(k, K.zero))
- return dup_strip(h)
- def dmp_from_dict(f, u, K):
- """
- Create a ``K[X]`` polynomial from a ``dict``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_from_dict
- >>> dmp_from_dict({(0, 0): ZZ(3), (0, 1): ZZ(2), (2, 1): ZZ(1)}, 1, ZZ)
- [[1, 0], [], [2, 3]]
- >>> dmp_from_dict({}, 0, ZZ)
- []
- """
- if not u:
- return dup_from_dict(f, K)
- if not f:
- return dmp_zero(u)
- coeffs = {}
- for monom, coeff in f.items():
- head, tail = monom[0], monom[1:]
- if head in coeffs:
- coeffs[head][tail] = coeff
- else:
- coeffs[head] = { tail: coeff }
- n, v, h = max(coeffs.keys()), u - 1, []
- for k in range(n, -1, -1):
- coeff = coeffs.get(k)
- if coeff is not None:
- h.append(dmp_from_dict(coeff, v, K))
- else:
- h.append(dmp_zero(v))
- return dmp_strip(h, u)
- def dup_to_dict(f, K=None, zero=False):
- """
- Convert ``K[x]`` polynomial to a ``dict``.
- Examples
- ========
- >>> from sympy.polys.densebasic import dup_to_dict
- >>> dup_to_dict([1, 0, 5, 0, 7])
- {(0,): 7, (2,): 5, (4,): 1}
- >>> dup_to_dict([])
- {}
- """
- if not f and zero:
- return {(0,): K.zero}
- n, result = len(f) - 1, {}
- for k in range(0, n + 1):
- if f[n - k]:
- result[(k,)] = f[n - k]
- return result
- def dup_to_raw_dict(f, K=None, zero=False):
- """
- Convert a ``K[x]`` polynomial to a raw ``dict``.
- Examples
- ========
- >>> from sympy.polys.densebasic import dup_to_raw_dict
- >>> dup_to_raw_dict([1, 0, 5, 0, 7])
- {0: 7, 2: 5, 4: 1}
- """
- if not f and zero:
- return {0: K.zero}
- n, result = len(f) - 1, {}
- for k in range(0, n + 1):
- if f[n - k]:
- result[k] = f[n - k]
- return result
- def dmp_to_dict(f, u, K=None, zero=False):
- """
- Convert a ``K[X]`` polynomial to a ``dict````.
- Examples
- ========
- >>> from sympy.polys.densebasic import dmp_to_dict
- >>> dmp_to_dict([[1, 0], [], [2, 3]], 1)
- {(0, 0): 3, (0, 1): 2, (2, 1): 1}
- >>> dmp_to_dict([], 0)
- {}
- """
- if not u:
- return dup_to_dict(f, K, zero=zero)
- if dmp_zero_p(f, u) and zero:
- return {(0,)*(u + 1): K.zero}
- n, v, result = dmp_degree(f, u), u - 1, {}
- if n == -oo:
- n = -1
- for k in range(0, n + 1):
- h = dmp_to_dict(f[n - k], v)
- for exp, coeff in h.items():
- result[(k,) + exp] = coeff
- return result
- def dmp_swap(f, i, j, u, K):
- """
- Transform ``K[..x_i..x_j..]`` to ``K[..x_j..x_i..]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_swap
- >>> f = ZZ.map([[[2], [1, 0]], []])
- >>> dmp_swap(f, 0, 1, 2, ZZ)
- [[[2], []], [[1, 0], []]]
- >>> dmp_swap(f, 1, 2, 2, ZZ)
- [[[1], [2, 0]], [[]]]
- >>> dmp_swap(f, 0, 2, 2, ZZ)
- [[[1, 0]], [[2, 0], []]]
- """
- if i < 0 or j < 0 or i > u or j > u:
- raise IndexError("0 <= i < j <= %s expected" % u)
- elif i == j:
- return f
- F, H = dmp_to_dict(f, u), {}
- for exp, coeff in F.items():
- H[exp[:i] + (exp[j],) +
- exp[i + 1:j] +
- (exp[i],) + exp[j + 1:]] = coeff
- return dmp_from_dict(H, u, K)
- def dmp_permute(f, P, u, K):
- """
- Return a polynomial in ``K[x_{P(1)},..,x_{P(n)}]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_permute
- >>> f = ZZ.map([[[2], [1, 0]], []])
- >>> dmp_permute(f, [1, 0, 2], 2, ZZ)
- [[[2], []], [[1, 0], []]]
- >>> dmp_permute(f, [1, 2, 0], 2, ZZ)
- [[[1], []], [[2, 0], []]]
- """
- F, H = dmp_to_dict(f, u), {}
- for exp, coeff in F.items():
- new_exp = [0]*len(exp)
- for e, p in zip(exp, P):
- new_exp[p] = e
- H[tuple(new_exp)] = coeff
- return dmp_from_dict(H, u, K)
- def dmp_nest(f, l, K):
- """
- Return a multivariate value nested ``l``-levels.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_nest
- >>> dmp_nest([[ZZ(1)]], 2, ZZ)
- [[[[1]]]]
- """
- if not isinstance(f, list):
- return dmp_ground(f, l)
- for i in range(l):
- f = [f]
- return f
- def dmp_raise(f, l, u, K):
- """
- Return a multivariate polynomial raised ``l``-levels.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_raise
- >>> f = ZZ.map([[], [1, 2]])
- >>> dmp_raise(f, 2, 1, ZZ)
- [[[[]]], [[[1]], [[2]]]]
- """
- if not l:
- return f
- if not u:
- if not f:
- return dmp_zero(l)
- k = l - 1
- return [ dmp_ground(c, k) for c in f ]
- v = u - 1
- return [ dmp_raise(c, l, v, K) for c in f ]
- def dup_deflate(f, K):
- """
- Map ``x**m`` to ``y`` in a polynomial in ``K[x]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_deflate
- >>> f = ZZ.map([1, 0, 0, 1, 0, 0, 1])
- >>> dup_deflate(f, ZZ)
- (3, [1, 1, 1])
- """
- if dup_degree(f) <= 0:
- return 1, f
- g = 0
- for i in range(len(f)):
- if not f[-i - 1]:
- continue
- g = igcd(g, i)
- if g == 1:
- return 1, f
- return g, f[::g]
- def dmp_deflate(f, u, K):
- """
- Map ``x_i**m_i`` to ``y_i`` in a polynomial in ``K[X]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_deflate
- >>> f = ZZ.map([[1, 0, 0, 2], [], [3, 0, 0, 4]])
- >>> dmp_deflate(f, 1, ZZ)
- ((2, 3), [[1, 2], [3, 4]])
- """
- if dmp_zero_p(f, u):
- return (1,)*(u + 1), f
- F = dmp_to_dict(f, u)
- B = [0]*(u + 1)
- for M in F.keys():
- for i, m in enumerate(M):
- B[i] = igcd(B[i], m)
- for i, b in enumerate(B):
- if not b:
- B[i] = 1
- B = tuple(B)
- if all(b == 1 for b in B):
- return B, f
- H = {}
- for A, coeff in F.items():
- N = [ a // b for a, b in zip(A, B) ]
- H[tuple(N)] = coeff
- return B, dmp_from_dict(H, u, K)
- def dup_multi_deflate(polys, K):
- """
- Map ``x**m`` to ``y`` in a set of polynomials in ``K[x]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_multi_deflate
- >>> f = ZZ.map([1, 0, 2, 0, 3])
- >>> g = ZZ.map([4, 0, 0])
- >>> dup_multi_deflate((f, g), ZZ)
- (2, ([1, 2, 3], [4, 0]))
- """
- G = 0
- for p in polys:
- if dup_degree(p) <= 0:
- return 1, polys
- g = 0
- for i in range(len(p)):
- if not p[-i - 1]:
- continue
- g = igcd(g, i)
- if g == 1:
- return 1, polys
- G = igcd(G, g)
- return G, tuple([ p[::G] for p in polys ])
- def dmp_multi_deflate(polys, u, K):
- """
- Map ``x_i**m_i`` to ``y_i`` in a set of polynomials in ``K[X]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_multi_deflate
- >>> f = ZZ.map([[1, 0, 0, 2], [], [3, 0, 0, 4]])
- >>> g = ZZ.map([[1, 0, 2], [], [3, 0, 4]])
- >>> dmp_multi_deflate((f, g), 1, ZZ)
- ((2, 1), ([[1, 0, 0, 2], [3, 0, 0, 4]], [[1, 0, 2], [3, 0, 4]]))
- """
- if not u:
- M, H = dup_multi_deflate(polys, K)
- return (M,), H
- F, B = [], [0]*(u + 1)
- for p in polys:
- f = dmp_to_dict(p, u)
- if not dmp_zero_p(p, u):
- for M in f.keys():
- for i, m in enumerate(M):
- B[i] = igcd(B[i], m)
- F.append(f)
- for i, b in enumerate(B):
- if not b:
- B[i] = 1
- B = tuple(B)
- if all(b == 1 for b in B):
- return B, polys
- H = []
- for f in F:
- h = {}
- for A, coeff in f.items():
- N = [ a // b for a, b in zip(A, B) ]
- h[tuple(N)] = coeff
- H.append(dmp_from_dict(h, u, K))
- return B, tuple(H)
- def dup_inflate(f, m, K):
- """
- Map ``y`` to ``x**m`` in a polynomial in ``K[x]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_inflate
- >>> f = ZZ.map([1, 1, 1])
- >>> dup_inflate(f, 3, ZZ)
- [1, 0, 0, 1, 0, 0, 1]
- """
- if m <= 0:
- raise IndexError("'m' must be positive, got %s" % m)
- if m == 1 or not f:
- return f
- result = [f[0]]
- for coeff in f[1:]:
- result.extend([K.zero]*(m - 1))
- result.append(coeff)
- return result
- def _rec_inflate(g, M, v, i, K):
- """Recursive helper for :func:`dmp_inflate`."""
- if not v:
- return dup_inflate(g, M[i], K)
- if M[i] <= 0:
- raise IndexError("all M[i] must be positive, got %s" % M[i])
- w, j = v - 1, i + 1
- g = [ _rec_inflate(c, M, w, j, K) for c in g ]
- result = [g[0]]
- for coeff in g[1:]:
- for _ in range(1, M[i]):
- result.append(dmp_zero(w))
- result.append(coeff)
- return result
- def dmp_inflate(f, M, u, K):
- """
- Map ``y_i`` to ``x_i**k_i`` in a polynomial in ``K[X]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_inflate
- >>> f = ZZ.map([[1, 2], [3, 4]])
- >>> dmp_inflate(f, (2, 3), 1, ZZ)
- [[1, 0, 0, 2], [], [3, 0, 0, 4]]
- """
- if not u:
- return dup_inflate(f, M[0], K)
- if all(m == 1 for m in M):
- return f
- else:
- return _rec_inflate(f, M, u, 0, K)
- def dmp_exclude(f, u, K):
- """
- Exclude useless levels from ``f``.
- Return the levels excluded, the new excluded ``f``, and the new ``u``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_exclude
- >>> f = ZZ.map([[[1]], [[1], [2]]])
- >>> dmp_exclude(f, 2, ZZ)
- ([2], [[1], [1, 2]], 1)
- """
- if not u or dmp_ground_p(f, None, u):
- return [], f, u
- J, F = [], dmp_to_dict(f, u)
- for j in range(0, u + 1):
- for monom in F.keys():
- if monom[j]:
- break
- else:
- J.append(j)
- if not J:
- return [], f, u
- f = {}
- for monom, coeff in F.items():
- monom = list(monom)
- for j in reversed(J):
- del monom[j]
- f[tuple(monom)] = coeff
- u -= len(J)
- return J, dmp_from_dict(f, u, K), u
- def dmp_include(f, J, u, K):
- """
- Include useless levels in ``f``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_include
- >>> f = ZZ.map([[1], [1, 2]])
- >>> dmp_include(f, [2], 1, ZZ)
- [[[1]], [[1], [2]]]
- """
- if not J:
- return f
- F, f = dmp_to_dict(f, u), {}
- for monom, coeff in F.items():
- monom = list(monom)
- for j in J:
- monom.insert(j, 0)
- f[tuple(monom)] = coeff
- u += len(J)
- return dmp_from_dict(f, u, K)
- def dmp_inject(f, u, K, front=False):
- """
- Convert ``f`` from ``K[X][Y]`` to ``K[X,Y]``.
- Examples
- ========
- >>> from sympy.polys.rings import ring
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_inject
- >>> R, x,y = ring("x,y", ZZ)
- >>> dmp_inject([R(1), x + 2], 0, R.to_domain())
- ([[[1]], [[1], [2]]], 2)
- >>> dmp_inject([R(1), x + 2], 0, R.to_domain(), front=True)
- ([[[1]], [[1, 2]]], 2)
- """
- f, h = dmp_to_dict(f, u), {}
- v = K.ngens - 1
- for f_monom, g in f.items():
- g = g.to_dict()
- for g_monom, c in g.items():
- if front:
- h[g_monom + f_monom] = c
- else:
- h[f_monom + g_monom] = c
- w = u + v + 1
- return dmp_from_dict(h, w, K.dom), w
- def dmp_eject(f, u, K, front=False):
- """
- Convert ``f`` from ``K[X,Y]`` to ``K[X][Y]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_eject
- >>> dmp_eject([[[1]], [[1], [2]]], 2, ZZ['x', 'y'])
- [1, x + 2]
- """
- f, h = dmp_to_dict(f, u), {}
- n = K.ngens
- v = u - K.ngens + 1
- for monom, c in f.items():
- if front:
- g_monom, f_monom = monom[:n], monom[n:]
- else:
- g_monom, f_monom = monom[-n:], monom[:-n]
- if f_monom in h:
- h[f_monom][g_monom] = c
- else:
- h[f_monom] = {g_monom: c}
- for monom, c in h.items():
- h[monom] = K(c)
- return dmp_from_dict(h, v - 1, K)
- def dup_terms_gcd(f, K):
- """
- Remove GCD of terms from ``f`` in ``K[x]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_terms_gcd
- >>> f = ZZ.map([1, 0, 1, 0, 0])
- >>> dup_terms_gcd(f, ZZ)
- (2, [1, 0, 1])
- """
- if dup_TC(f, K) or not f:
- return 0, f
- i = 0
- for c in reversed(f):
- if not c:
- i += 1
- else:
- break
- return i, f[:-i]
- def dmp_terms_gcd(f, u, K):
- """
- Remove GCD of terms from ``f`` in ``K[X]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_terms_gcd
- >>> f = ZZ.map([[1, 0], [1, 0, 0], [], []])
- >>> dmp_terms_gcd(f, 1, ZZ)
- ((2, 1), [[1], [1, 0]])
- """
- if dmp_ground_TC(f, u, K) or dmp_zero_p(f, u):
- return (0,)*(u + 1), f
- F = dmp_to_dict(f, u)
- G = monomial_min(*list(F.keys()))
- if all(g == 0 for g in G):
- return G, f
- f = {}
- for monom, coeff in F.items():
- f[monomial_div(monom, G)] = coeff
- return G, dmp_from_dict(f, u, K)
- def _rec_list_terms(g, v, monom):
- """Recursive helper for :func:`dmp_list_terms`."""
- d, terms = dmp_degree(g, v), []
- if not v:
- for i, c in enumerate(g):
- if not c:
- continue
- terms.append((monom + (d - i,), c))
- else:
- w = v - 1
- for i, c in enumerate(g):
- terms.extend(_rec_list_terms(c, w, monom + (d - i,)))
- return terms
- def dmp_list_terms(f, u, K, order=None):
- """
- List all non-zero terms from ``f`` in the given order ``order``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_list_terms
- >>> f = ZZ.map([[1, 1], [2, 3]])
- >>> dmp_list_terms(f, 1, ZZ)
- [((1, 1), 1), ((1, 0), 1), ((0, 1), 2), ((0, 0), 3)]
- >>> dmp_list_terms(f, 1, ZZ, order='grevlex')
- [((1, 1), 1), ((1, 0), 1), ((0, 1), 2), ((0, 0), 3)]
- """
- def sort(terms, O):
- return sorted(terms, key=lambda term: O(term[0]), reverse=True)
- terms = _rec_list_terms(f, u, ())
- if not terms:
- return [((0,)*(u + 1), K.zero)]
- if order is None:
- return terms
- else:
- return sort(terms, monomial_key(order))
- def dup_apply_pairs(f, g, h, args, K):
- """
- Apply ``h`` to pairs of coefficients of ``f`` and ``g``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_apply_pairs
- >>> h = lambda x, y, z: 2*x + y - z
- >>> dup_apply_pairs([1, 2, 3], [3, 2, 1], h, (1,), ZZ)
- [4, 5, 6]
- """
- n, m = len(f), len(g)
- if n != m:
- if n > m:
- g = [K.zero]*(n - m) + g
- else:
- f = [K.zero]*(m - n) + f
- result = []
- for a, b in zip(f, g):
- result.append(h(a, b, *args))
- return dup_strip(result)
- def dmp_apply_pairs(f, g, h, args, u, K):
- """
- Apply ``h`` to pairs of coefficients of ``f`` and ``g``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dmp_apply_pairs
- >>> h = lambda x, y, z: 2*x + y - z
- >>> dmp_apply_pairs([[1], [2, 3]], [[3], [2, 1]], h, (1,), 1, ZZ)
- [[4], [5, 6]]
- """
- if not u:
- return dup_apply_pairs(f, g, h, args, K)
- n, m, v = len(f), len(g), u - 1
- if n != m:
- if n > m:
- g = dmp_zeros(n - m, v, K) + g
- else:
- f = dmp_zeros(m - n, v, K) + f
- result = []
- for a, b in zip(f, g):
- result.append(dmp_apply_pairs(a, b, h, args, v, K))
- return dmp_strip(result, u)
- def dup_slice(f, m, n, K):
- """Take a continuous subsequence of terms of ``f`` in ``K[x]``. """
- k = len(f)
- if k >= m:
- M = k - m
- else:
- M = 0
- if k >= n:
- N = k - n
- else:
- N = 0
- f = f[N:M]
- if not f:
- return []
- else:
- return f + [K.zero]*m
- def dmp_slice(f, m, n, u, K):
- """Take a continuous subsequence of terms of ``f`` in ``K[X]``. """
- return dmp_slice_in(f, m, n, 0, u, K)
- def dmp_slice_in(f, m, n, j, u, K):
- """Take a continuous subsequence of terms of ``f`` in ``x_j`` in ``K[X]``. """
- if j < 0 or j > u:
- raise IndexError("-%s <= j < %s expected, got %s" % (u, u, j))
- if not u:
- return dup_slice(f, m, n, K)
- f, g = dmp_to_dict(f, u), {}
- for monom, coeff in f.items():
- k = monom[j]
- if k < m or k >= n:
- monom = monom[:j] + (0,) + monom[j + 1:]
- if monom in g:
- g[monom] += coeff
- else:
- g[monom] = coeff
- return dmp_from_dict(g, u, K)
- def dup_random(n, a, b, K):
- """
- Return a polynomial of degree ``n`` with coefficients in ``[a, b]``.
- Examples
- ========
- >>> from sympy.polys.domains import ZZ
- >>> from sympy.polys.densebasic import dup_random
- >>> dup_random(3, -10, 10, ZZ) #doctest: +SKIP
- [-2, -8, 9, -4]
- """
- f = [ K.convert(random.randint(a, b)) for _ in range(0, n + 1) ]
- while not f[0]:
- f[0] = K.convert(random.randint(a, b))
- return f
|